| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231 |
- #include <sys/poll.h>
- #include <string.h>
- #include <stdio.h>
- #include <stdlib.h>
- #include <sys/types.h>
- #include <sys/wait.h>
- #include <spawn.h>
- #include <unistd.h>
- #include <fcntl.h>
- #include <assert.h>
- #include <time.h>
- #include <pthread.h>
- #include "hiredis/hiredis.h"
- #include "cjson/cJSON.h"
- #include "iniparser/iniparser.h"
- #define Boolean int
- #define TRUE 1
- #define FALSE 0
- #define MAX_PIPE_BUFSIZE 256
- //BARESIP_STATUS
- #define IDLE 0
- #define INUSE 1
- #define RING 2
- #define RINGING 3
- #define HOLD 4
- #define OFFLINE 5
- #define DIALING 6
- #define LOOPSTART 7
- //BARESIP_REG
- #define REGISTER_FAIL 0
- #define REGISTER_OK 1
- //REDIS_CHANNEL
- #define BARESIP_CHAN 0
- #define GPIO_CHAN 1
- //GPIO_STATUS
- #define GPIO_OFF 0
- #define GPIO_ON 1
- #define SPK_CONF "/etc/speaker.conf"
- #define unix_socket_path "/tmp/redis.sock"
- //operator log type
- #define BTN "BUTTON"
- #define FUN "FUNCTION"
- #define STA "SIP STATE"
- #define GPIO_RELAY "gpio67"
- #define VAR_IP "${ip}"
- #define VAR_MAC "${mac}"
- #define VAR_UA "${ua}"
- #define VAR_NUM "${number}"
- struct VLC_INFO{
- Boolean state;
- pid_t pid;
- char param[256];
- };
- typedef struct _playInfo{
- int duration;
- int volume;
- char url[128];
- } PlayInfo;
- typedef struct {
- redisContext *context;
- const char *socket_path;
- time_t last_activity;
- } redis_client_t;
- static int BARESIP_STATUS = OFFLINE;
- static int DEBUG = FALSE;
- static int ACCOUNT1_REG = REGISTER_FAIL;
- static int ACCOUNT2_REG = REGISTER_FAIL;
- static int ACCOUNT3_REG = REGISTER_FAIL;
- static int ACCOUNTP2P_REG = REGISTER_FAIL;
- static int PLAYING = FALSE;
- static int delay = 0;
- struct VLC_INFO vlcInfo;
- static redis_client_t *redisClient;
- redis_client_t* create_redis_client(const char *socket_path) {
- redis_client_t *client = malloc(sizeof(redis_client_t));
- client->socket_path = socket_path;
- client->context = redisConnectUnix(socket_path);
- client->last_activity = time(NULL);
- return client;
- }
- int ensure_connected(redis_client_t *client) {
- if (client->context == NULL || client->context->err) {
- if (client->context) {
- redisFree(client->context);
- }
- client->context = redisConnectUnix(client->socket_path);
- if (client->context == NULL || client->context->err) {
- return -1; // 连接失败
- }
- }
- client->last_activity = time(NULL);
- return 0;
- }
- void redis_command_safe(const char *format, char *value) {
- if (ensure_connected(redisClient) == 0) {
- redisReply *reply = redisCommand(redisClient->context, format, value);
- if (reply) {
- // 处理回复
- freeReplyObject(reply);
- }
- }
- }
- /*
- * @cmd 执行命令
- * @value 命令结果指针
- * @lenth 存储结果长度
- int GetCmdValue(char *cmd, char *value, int lenth)
- {
- bzero(value, lenth);
- FILE *fp = popen(cmd,"r");
- if(fp != NULL){
- fread(value, 1, lenth, fp);
- pclose(fp);
- } else {
- printf("Handle \"%s\" failed.\n", cmd);
- return FALSE;
- }
- return TRUE;
- }
- */
- int GetCmdValue(char *file, char *key, char *value, int lenth)
- {
- dictionary * ini ;
- ini = iniparser_load(file);
-
- if (ini==NULL) {
- fprintf(stderr, "cannot parse file: %s\n", file);
- return FALSE ;
- }
- strcpy(value, iniparser_getstring(ini, key, ""));
- if(DEBUG)
- printf("keystr: \"%s\" ; value: %s.\n", key, value);
- iniparser_freedict(ini);
- return TRUE;
- }
- void writeLog(char *type,char *action, char *remark)
- {
- char logstr[256];
- sprintf(logstr, "%s,%s,%s", type, action, remark);
- redis_command_safe("LPUSH writelog-channel %s", logstr);
- }
- char *strrpl(char *s, const char *s1, const char *s2)
- {
- char *ptr;
- while (ptr = strstr(s, s1)) /* 如果在s中找到s1 */
- {
- memmove(ptr + strlen(s2) , ptr + strlen(s1), strlen(ptr) - strlen(s1) + 1);
- memcpy(ptr, &s2[0], strlen(s2));
- }
- return s;
- }
- //控制功放的开启/关闭,TRUE/FALSE
- void amplifier_switch(Boolean enable){
- if(enable)
- {
- system("/etc/scripts/pa_mute.sh 0");
- }
- else
- {
- system("/etc/scripts/pa_mute.sh 1");
- }
- }
- Boolean get_ip(char * pv)
- {
- FILE * fp;
- char cmdbuf[128], value[32];
- char *tmp=NULL;
- sprintf(cmdbuf,"/sbin/ifconfig eth0 | grep inet | cut -d\":\" -f2 | cut -d\" \" -f1");
- fp = popen(cmdbuf, "r");
- if (fp == NULL) {
- // printf("Fail to open pipe\n");
- return FALSE;
- }
- memset(value,0,sizeof(value));
- if (!feof(fp) && fgets(value,32,fp) != NULL)
- ;
- // printf("value:%s\n", value);
- else {
- printf("ip wrong\n");
- return FALSE;
- }
- pclose(fp);
- if(strlen(value) < 10)
- return FALSE;
- if(tmp = strstr(value,"\n"))
- {
- *tmp = '\0';
- }
- strcpy(pv,value);
- return TRUE;
- }
- Boolean get_mac(char * pv)
- {
- FILE * fp;
- char cmdbuf[128], value[32];
- char *tmp=NULL;
- sprintf(cmdbuf,"ifconfig eth0 | grep HWaddr | tr -d : | awk '{print $5}'");
- fp = popen(cmdbuf, "r");
- if (fp == NULL) {
- // printf("Fail to open pipe\n");
- return FALSE;
- }
- memset(value,0,sizeof(value));
- if (!feof(fp) && fgets(value,32,fp) != NULL)
- ;
- // printf("value:%s\n", value);
- else {
- printf("ip wrong\n");
- return FALSE;
- }
- pclose(fp);
- if(strlen(value) < 10)
- return FALSE;
- if(tmp = strstr(value,"\n"))
- {
- *tmp = '\0';
- }
- strcpy(pv,value);
- return TRUE;
- }
- void action_url(char *url)
- {
- char cmd[320];
- sprintf(cmd,"curl -k --connect-timeout 5 '%s' 2>/dev/null &",url);
- if(DEBUG)
- printf( "Command: %s\n", cmd);
- system(cmd);
- writeLog( FUN, "API HTTP Request", url );
- }
- //发送控制指令
- void control_cmd(int channel, char *cmd)
- {
- char redisCmd[256];
- switch (channel)
- {
- case BARESIP_CHAN:
- if(DEBUG)
- printf( "control-channel [%s]\n", cmd );
- redis_command_safe("LPUSH control-channel %s", cmd );
- break;
- case GPIO_CHAN:
- if(DEBUG)
- printf( "output-channel [%s]\n", cmd );
- redis_command_safe("LPUSH output-channel %s", cmd );
- break;
- default:
- redis_command_safe("LPUSH control-channel %s", cmd );
- break;
- }
- }
- void outputControl(char *id, int enable){
- char cmd[64];
- int channel = GPIO_CHAN;
- if(enable){
- char output_type[32];
- GetCmdValue(SPK_CONF, "relay_ctrl:type", output_type, sizeof(output_type));
- sprintf(cmd,"{\"id\":\"%s\",\"type\":\"%s\"}",id,output_type);
- control_cmd(channel,cmd);
- }
- else
- {
- sprintf(cmd,"{\"id\":\"%s\",\"type\":\"Off\"}",id);
- control_cmd(channel,cmd);
- }
- }
- //gpio延时控制
- void *gpioDelayControl()
- {
- usleep(delay*1000*1000);
- outputControl(GPIO_RELAY, GPIO_OFF);
- if(DEBUG)
- printf( "gpio135 set off\n" );
- }
- //呼入触发
- void incomingTrigger(cJSON *pJson)
- {
- char enable[8],url[256],ipaddr[16],macaddr[16], peeruri[128];
- GetCmdValue(SPK_CONF, "call_action_url:incoming_enable", enable, sizeof(enable));
- if(strcmp(enable,"yes") == 0)
- {
- GetCmdValue(SPK_CONF, "call_action_url:incoming_url", url, sizeof(url));
- if(strstr(url,VAR_IP))
- {
- if(get_ip(ipaddr))
- strcpy(url, strrpl(url, VAR_IP, ipaddr));
- }
- if(strstr(url,VAR_MAC))
- {
- if(get_mac(macaddr))
- strcpy(url, strrpl(url, VAR_MAC, macaddr));
- }
- if(strstr(url,VAR_UA))
- {
- strcpy(url, strrpl(url, VAR_UA, cJSON_GetObjectItem(pJson, "exten")->valuestring));
- }
- if(strstr(url,VAR_NUM))
- {
- char *ret, number[64];
- strcpy(peeruri, cJSON_GetObjectItem(pJson, "peeruri")->valuestring);
- ret = strchr(peeruri, '@');
- if(ret)
- {
- memset(number,0,sizeof(number));
- strncpy(number,peeruri,ret - peeruri);
- strcpy(url, strrpl(url, VAR_NUM, number + 4));
- }
-
- }
- action_url(url);
- }
- }
- //呼出触发
- void outgoingTrigger(cJSON *pJson)
- {
- char enable[8],url[256],ipaddr[16],macaddr[16], peeruri[128];
- GetCmdValue(SPK_CONF, "call_action_url:outgoing_enable", enable, sizeof(enable));
- if(strcmp(enable,"yes") == 0)
- {
- GetCmdValue(SPK_CONF, "call_action_url:outgoing_url", url, sizeof(url));
- if(strstr(url,VAR_IP))
- {
- if(get_ip(ipaddr))
- strcpy(url, strrpl(url, VAR_IP, ipaddr));
- }
- if(strstr(url,VAR_MAC))
- {
- if(get_mac(macaddr))
- strcpy(url, strrpl(url, VAR_MAC, macaddr));
- }
- if(strstr(url,VAR_UA))
- {
- strcpy(url, strrpl(url, VAR_UA, cJSON_GetObjectItem(pJson, "exten")->valuestring));
- }
- if(strstr(url,VAR_NUM))
- {
- char *ret, number[64];
- strcpy(peeruri, cJSON_GetObjectItem(pJson, "peeruri")->valuestring);
- ret = strchr(peeruri, '@');
- if(ret)
- {
- memset(number,0,sizeof(number));
- strncpy(number,peeruri,ret - peeruri);
- strcpy(url, strrpl(url, VAR_NUM, number + 4));
- }
- }
- action_url(url);
- }
- }
- //应答触发
- void answeredTrigger(cJSON *pJson)
- {
- char enable[8],url[256],ipaddr[16],macaddr[16], peeruri[128];
- GetCmdValue(SPK_CONF, "call_action_url:answered_enable", enable, sizeof(enable));
- if(strcmp(enable,"yes") == 0)
- {
- GetCmdValue(SPK_CONF, "call_action_url:answered_url", url, sizeof(url));
- if(strstr(url,VAR_IP))
- {
- if(get_ip(ipaddr))
- strcpy(url, strrpl(url, VAR_IP, ipaddr));
- }
- if(strstr(url,VAR_MAC))
- {
- if(get_mac(macaddr))
- strcpy(url, strrpl(url, VAR_MAC, macaddr));
- }
- if(strstr(url,VAR_UA))
- {
- strcpy(url, strrpl(url, VAR_UA, cJSON_GetObjectItem(pJson, "exten")->valuestring));
- }
- if(strstr(url,VAR_NUM))
- {
- char *ret, number[64];
- strcpy(peeruri, cJSON_GetObjectItem(pJson, "peeruri")->valuestring);
- ret = strchr(peeruri, '@');
- if(ret)
- {
- memset(number,0,sizeof(number));
- strncpy(number,peeruri,ret - peeruri);
- strcpy(url, strrpl(url, VAR_NUM, number + 4));
- }
- }
- action_url(url);
- }
- }
- //应答触发
- void hangupTrigger(cJSON *pJson)
- {
- char enable[8],url[256],ipaddr[16],macaddr[16], peeruri[128];
- GetCmdValue(SPK_CONF, "call_action_url:hangup_enable", enable, sizeof(enable));
- if(strcmp(enable,"yes") == 0)
- {
- GetCmdValue(SPK_CONF, "call_action_url:hangup_url", url, sizeof(url));
- if(strstr(url,VAR_IP))
- {
- if(get_ip(ipaddr))
- strcpy(url, strrpl(url, VAR_IP, ipaddr));
- }
- if(strstr(url,VAR_MAC))
- {
- if(get_mac(macaddr))
- strcpy(url, strrpl(url, VAR_MAC, macaddr));
- }
- if(strstr(url,VAR_UA))
- {
- strcpy(url, strrpl(url, VAR_UA, cJSON_GetObjectItem(pJson, "exten")->valuestring));
- }
- if(strstr(url,VAR_NUM))
- {
- char *ret, number[64];
- strcpy(peeruri, cJSON_GetObjectItem(pJson, "peeruri")->valuestring);
- ret = strchr(peeruri, '@');
- if(ret)
- {
- memset(number,0,sizeof(number));
- strncpy(number,peeruri,ret - peeruri);
- strcpy(url, strrpl(url, VAR_NUM, number + 4));
- }
- }
- action_url(url);
- }
- }
- //baresip状态监控
- void ProcessReply( redisReply * pReply )
- {
- cJSON *pJson = NULL;
- redisReply * pSubReply = NULL;
- if ( pReply != NULL && pReply->elements == 3 )
- {
- pSubReply = pReply->element[2];
- if(DEBUG)
- printf( "Msg [%s]\n", pSubReply->str );
- pJson = cJSON_Parse(pSubReply->str);
- if ( pJson ) {
- if(strcmp(cJSON_GetObjectItem(pJson, "type")->valuestring, "CALL_ESTABLISHED") == 0)
- {
- //通话
- BARESIP_STATUS = INUSE;
- answeredTrigger(pJson);
- }
- else if(strcmp(cJSON_GetObjectItem(pJson, "direction")->valuestring, "incoming") == 0 &&
- strcmp(cJSON_GetObjectItem(pJson, "type")->valuestring, "CALL_CLOSED") == 0)
- {
- //挂断
- if(BARESIP_STATUS != OFFLINE){
- BARESIP_STATUS = IDLE;
- }
- hangupTrigger(pJson);
- }
- else if(strcmp(cJSON_GetObjectItem(pJson, "direction")->valuestring, "outgoing") == 0 &&
- strcmp(cJSON_GetObjectItem(pJson, "type")->valuestring, "CALL_CLOSED") == 0)
- {
- //挂断
- if(BARESIP_STATUS != OFFLINE){
- BARESIP_STATUS = IDLE;
- }
- hangupTrigger(pJson);
- }
- else if(strcmp(cJSON_GetObjectItem(pJson, "direction")->valuestring, "incoming") == 0 &&
- strcmp(cJSON_GetObjectItem(pJson, "type")->valuestring, "CALL_INCOMING") == 0)
- {
- //呼入振铃状态
- if(BARESIP_STATUS == IDLE)
- {
- BARESIP_STATUS = RING;
- incomingTrigger(pJson);
- }
- }
- else if(strcmp(cJSON_GetObjectItem(pJson, "direction")->valuestring, "outgoing") == 0 &&
- strcmp(cJSON_GetObjectItem(pJson, "type")->valuestring, "CALL_OUTGOING") == 0)
- {
- //呼出回铃状态
- if(BARESIP_STATUS == IDLE || BARESIP_STATUS == DIALING)
- {
- BARESIP_STATUS = RINGING;
- outgoingTrigger(pJson);
- }
- }
- else if(strcmp(cJSON_GetObjectItem(pJson, "type")->valuestring, "REGISTER_OK") == 0)
- {
- //如果是注册成功点亮指示灯
- char enac1[8],enac2[8],enac3[8],accountaor1[192], accountaor2[192], accountaor3[192];
- char account1[32], domain1[128], account2[32], domain2[128], account3[32], domain3[128];
- if(BARESIP_STATUS == OFFLINE || BARESIP_STATUS == DIALING)
- {
- BARESIP_STATUS = IDLE;
- }
- if(cJSON_GetObjectItem(pJson, "accountaor") != NULL)
- {
- GetCmdValue(SPK_CONF, "account_info_1:enable", enac1, sizeof(enac1));
- if(strcmp(enac1, "yes") == 0 && ACCOUNT1_REG == REGISTER_FAIL)
- {
- GetCmdValue(SPK_CONF, "account_info_1:username", account1, sizeof(account1));
- GetCmdValue(SPK_CONF, "account_info_1:domain", domain1, sizeof(domain1));
- if(strlen(domain1) == 0)
- {
- GetCmdValue(SPK_CONF, "account_info_1:server", domain1, sizeof(domain1));
- }
- memset(accountaor1, '\0', sizeof(accountaor1));
- sprintf(accountaor1, "sip:%s@%s", account1, domain1);
- if (strcmp(cJSON_GetObjectItem(pJson, "accountaor")->valuestring, accountaor1) == 0)
- {
- ACCOUNT1_REG = REGISTER_OK;
- cJSON_Delete(pJson);
- return;
- }
- }
- GetCmdValue(SPK_CONF, "account_info_2:enable", enac2, sizeof(enac2));
- if(strcmp(enac2, "yes") == 0 && ACCOUNT2_REG == REGISTER_FAIL)
- {
- GetCmdValue(SPK_CONF, "account_info_2:username", account2, sizeof(account2));
- GetCmdValue(SPK_CONF, "account_info_2:domain", domain2, sizeof(domain2));
- if(strlen(domain2) == 0)
- {
- GetCmdValue(SPK_CONF, "account_info_2:server", domain2, sizeof(domain2));
- }
- memset(accountaor2, '\0', sizeof(accountaor2));
- sprintf(accountaor2, "sip:%s@%s", account2, domain2);
- if (strcmp(cJSON_GetObjectItem(pJson, "accountaor")->valuestring, accountaor2) == 0)
- {
- ACCOUNT2_REG = REGISTER_OK;
- cJSON_Delete(pJson);
- return;
- }
- }
- GetCmdValue(SPK_CONF, "account_info_3:enable", enac3, sizeof(enac3));
- if(strcmp(enac3, "yes") == 0 && ACCOUNT3_REG == REGISTER_FAIL)
- {
- GetCmdValue(SPK_CONF, "account_info_3:username", account3, sizeof(account3));
- GetCmdValue(SPK_CONF, "account_info_3:domain", domain3, sizeof(domain3));
- if(strlen(domain3) == 0)
- {
- GetCmdValue(SPK_CONF, "account_info_3:server", domain3, sizeof(domain3));
- }
- memset(accountaor3, '\0', sizeof(accountaor3));
- sprintf(accountaor3, "sip:%s@%s", account3, domain3);
- if (strcmp(cJSON_GetObjectItem(pJson, "accountaor")->valuestring, accountaor3) == 0)
- {
- ACCOUNT3_REG = REGISTER_OK;
- cJSON_Delete(pJson);
- return;
- }
- }
- }
- }
- else if(strcmp(cJSON_GetObjectItem(pJson, "type")->valuestring, "REGISTER_FAIL") == 0 )
- {
- char enac1[8],enac2[8],enac3[8],accountaor1[192], accountaor2[192], accountaor3[192];
- char account1[32], domain1[128], account2[32], domain2[128], account3[32], domain3[128];
- if(cJSON_GetObjectItem(pJson, "accountaor") != NULL)
- {
- GetCmdValue(SPK_CONF, "account_info_1:enable", enac1, sizeof(enac1));
- if(strcmp(enac1, "yes") == 0 && ACCOUNT1_REG == REGISTER_OK)
- {
- GetCmdValue(SPK_CONF, "account_info_1:username", account1, sizeof(account1));
- GetCmdValue(SPK_CONF, "account_info_1:domain", domain1, sizeof(domain1));
- if(strlen(domain1) == 0)
- {
- GetCmdValue(SPK_CONF, "account_info_1:server", domain1, sizeof(domain1));
- }
- memset(accountaor1, '\0', sizeof(accountaor1));
- sprintf(accountaor1, "sip:%s@%s", account1, domain1);
- if (strcmp(cJSON_GetObjectItem(pJson, "accountaor")->valuestring, accountaor1) == 0)
- {
- ACCOUNT1_REG = REGISTER_FAIL;
- if( ACCOUNT2_REG == REGISTER_FAIL && ACCOUNT3_REG == REGISTER_FAIL && ACCOUNTP2P_REG == REGISTER_FAIL ){
- BARESIP_STATUS = OFFLINE;
- }
- cJSON_Delete(pJson);
- return;
- }
- }
- GetCmdValue(SPK_CONF, "account_info_2:enable", enac2, sizeof(enac2));
- if(strcmp(enac2, "yes") == 0 && ACCOUNT2_REG == REGISTER_OK)
- {
- GetCmdValue(SPK_CONF, "account_info_2:username", account2, sizeof(account2));
- GetCmdValue(SPK_CONF, "account_info_2:domain", domain2, sizeof(domain2));
- if(strlen(domain2) == 0)
- {
- GetCmdValue(SPK_CONF, "account_info_2:server", domain2, sizeof(domain2));
- }
- memset(accountaor2, '\0', sizeof(accountaor2));
- sprintf(accountaor2, "sip:%s@%s", account2, domain2);
- if (strcmp(cJSON_GetObjectItem(pJson, "accountaor")->valuestring, accountaor2) == 0)
- {
- ACCOUNT2_REG = REGISTER_FAIL;
- if( ACCOUNT1_REG == REGISTER_FAIL && ACCOUNT3_REG == REGISTER_FAIL && ACCOUNTP2P_REG == REGISTER_FAIL ){
- BARESIP_STATUS = OFFLINE;
- }
- cJSON_Delete(pJson);
- return;
- }
- }
- GetCmdValue(SPK_CONF, "account_info_3:enable", enac3, sizeof(enac3));
- if(strcmp(enac3, "yes") == 0 && ACCOUNT3_REG == REGISTER_OK)
- {
- GetCmdValue(SPK_CONF, "account_info_3:username", account3, sizeof(account3));
- GetCmdValue(SPK_CONF, "account_info_3:domain", domain3, sizeof(domain3));
- if(strlen(domain3) == 0)
- {
- GetCmdValue(SPK_CONF, "account_info_3:server", domain3, sizeof(domain3));
- }
- memset(accountaor3, '\0', sizeof(accountaor3));
- sprintf(accountaor3, "sip:%s@%s", account3, domain3);
- if (strcmp(cJSON_GetObjectItem(pJson, "accountaor")->valuestring, accountaor3) == 0)
- {
- ACCOUNT3_REG = REGISTER_FAIL;
- if( ACCOUNT1_REG == REGISTER_FAIL && ACCOUNT2_REG == REGISTER_FAIL && ACCOUNTP2P_REG == REGISTER_FAIL ){
- BARESIP_STATUS = OFFLINE;
- }
- cJSON_Delete(pJson);
- return;
- }
- }
- }
- }
- else if(strcmp(cJSON_GetObjectItem(pJson, "type")->valuestring, "EXIT") == 0)
- {
- BARESIP_STATUS = OFFLINE;
- ACCOUNT1_REG = REGISTER_FAIL;
- ACCOUNT2_REG = REGISTER_FAIL;
- ACCOUNT3_REG = REGISTER_FAIL;
- }
- else if(cJSON_GetObjectItem(pJson, "event")->type == 1 && cJSON_GetObjectItem(pJson, "event")->valueint == 0){
- if(strncmp(cJSON_GetObjectItem(pJson, "data")->valuestring,"\n--- User Agents",16) == 0)
- {
- char p2penable[8];
- GetCmdValue(SPK_CONF, "account_info_p2p:enable", p2penable, sizeof(p2penable));
- if(strcmp(p2penable,"yes") == 0)
- {
- ACCOUNTP2P_REG = REGISTER_OK;
- BARESIP_STATUS = IDLE;
- }
- else
- {
- ACCOUNTP2P_REG = REGISTER_FAIL;
- }
- }
- }
- if(DEBUG)
- printf( "Baresip Status is: %d\n", BARESIP_STATUS );
- }else{
- printf( "parse failed!\n");
- }
- if(pJson != NULL) cJSON_Delete(pJson);
- }
- }
- /*
- * 订阅baresip实时状态.
- */
- void *baresip_status()
- {
- redisContext * pContext = redisConnectUnix(unix_socket_path);
- if ( NULL == pContext || pContext->err == 1 )
- {
- printf( "%s\n", pContext->errstr );
- exit( -1 );
- }
- char * pKey = "session-channel";
- redisReply * pReply = redisCommand( pContext, "SUBSCRIBE %s", pKey );
- freeReplyObject( pReply );
- while ( redisGetReply( pContext, (void **)&pReply ) == REDIS_OK )
- {
- ProcessReply( pReply );
- freeReplyObject( pReply );
- }
- redisFree( pContext );
- }
- int get_line(int * line_id)
- {
- char enac[8], strtmp[32];
- int id = 0;
- memset(line_id,-1,sizeof(line_id));
- for(int i = 1; i < 4;i ++)
- {
- bzero(strtmp, sizeof(strtmp));
- sprintf(strtmp,"account_info_%d:enable",i);
- GetCmdValue(SPK_CONF, strtmp, enac, sizeof(enac));
- if(strcmp(enac,"yes") == 0)
- {
- line_id[i] = id;
- id ++;
- }
- }
- return TRUE;
- }
- void sipphone_call(char *number, char *line)
- {
- char cmd[MAX_PIPE_BUFSIZE];
- char accountaor[192],strtmp[64];
- char account[32],domain[128];
- int channel = BARESIP_CHAN, line_id[4];
- if(DEBUG)
- printf( "BARESIP_STATUS [%d]\n", BARESIP_STATUS );
- if(BARESIP_STATUS == IDLE)
- {
- BARESIP_STATUS = DIALING;
- if(strlen(number) == 0)
- {
- BARESIP_STATUS = IDLE;
- return;
- }
- get_line(line_id);
- if(strcmp(line,"auto") == 0)
- {
- if(DEBUG)
- printf("ACCOUNT1 is %d, ACCOUNT2 is %d, ACCOUNT3 is %d\n",ACCOUNT1_REG,ACCOUNT2_REG,ACCOUNT3_REG);
- if(ACCOUNT1_REG == REGISTER_OK)
- {
- if(line_id[1] == -1)
- {
- BARESIP_STATUS = IDLE;
- return;
- }
- sprintf(cmd,"{\"cmd\":\"dial\",\"data\":\"%s %d\"}",number, line_id[1]);
- }
- else if(ACCOUNT2_REG == REGISTER_OK)
- {
- if(line_id[2] == -1)
- {
- BARESIP_STATUS = IDLE;
- return;
- }
- sprintf(cmd,"{\"cmd\":\"dial\",\"data\":\"%s %d\"}",number, line_id[2]);
- }
- else if(ACCOUNT3_REG == REGISTER_OK)
- {
- if(line_id[3] == -1)
- {
- BARESIP_STATUS = IDLE;
- return;
- }
- sprintf(cmd,"{\"cmd\":\"dial\",\"data\":\"%s %d\"}",number, line_id[3]);
- }
- else
- {
- BARESIP_STATUS = IDLE;
- return;
- }
- }
- else if (strcmp(line, "account_info_1") == 0)
- {
- if(line_id[1] == -1 || ACCOUNT1_REG != REGISTER_OK)
- {
- BARESIP_STATUS = IDLE;
- return;
- }
- sprintf(cmd,"{\"cmd\":\"dial\",\"data\":\"%s %d\"}",number, line_id[1]);
- }
- else if (strcmp(line, "account_info_2") == 0)
- {
- if(line_id[2] == -1 || ACCOUNT2_REG != REGISTER_OK)
- {
- BARESIP_STATUS = IDLE;
- return;
- }
- sprintf(cmd,"{\"cmd\":\"dial\",\"data\":\"%s %d\"}",number, line_id[2]);
- }
- else if (strcmp(line, "account_info_3") == 0)
- {
- if(line_id[3] == -1 || ACCOUNT3_REG != REGISTER_OK)
- {
- BARESIP_STATUS = IDLE;
- return;
- }
- sprintf(cmd,"{\"cmd\":\"dial\",\"data\":\"%s %d\"}",number, line_id[3]);
- }
- else if(strcmp(line,"p2p") == 0)
- {
- sprintf(cmd,"{\"cmd\":\"dial\",\"data\":\"%s\"}",number);
- }
-
- if(DEBUG)
- printf( "dial [%s]\n", cmd );
- control_cmd(channel, cmd);
- sprintf(strtmp, "%s <%s>", number, line);
- writeLog( FUN, "API Call", strtmp );
- }
- }
- void sipphone_answer()
- {
- char cmd[MAX_PIPE_BUFSIZE];
- int channel = BARESIP_CHAN;
- if(DEBUG)
- printf( "BARESIP_STATUS [%d]\n", BARESIP_STATUS );
- if(BARESIP_STATUS == RING)
- {
- strcpy(cmd,"{\"cmd\":\"accept\",\"data\":\"\"}");
- if(DEBUG)
- printf( "answer call\n" );
- control_cmd(channel, cmd);
- writeLog( FUN, "API Answer", "" );
- }
- }
- void sipphone_hangup()
- {
- char cmd[MAX_PIPE_BUFSIZE];
- int channel = BARESIP_CHAN;
- if(DEBUG)
- printf( "BARESIP_STATUS [%d]\n", BARESIP_STATUS );
- if(BARESIP_STATUS == RINGING || BARESIP_STATUS == INUSE)
- {
- strcpy(cmd,"{\"cmd\":\"hangup\",\"data\":\"\"}");
- if(DEBUG)
- printf( "hangup call\n" );
- control_cmd(channel, cmd);
- writeLog( FUN, "API Hangup", "" );
- }
- }
- void sipphone_loop_start()
- {
- char cmd[MAX_PIPE_BUFSIZE], hversion[16];
- int channel = BARESIP_CHAN;
- if(DEBUG)
- printf( "BARESIP_STATUS [%d]\n", BARESIP_STATUS );
- if(BARESIP_STATUS == IDLE || BARESIP_STATUS == OFFLINE)
- {
- strcpy(cmd,"{\"cmd\":\"auloop\",\"data\":\"48000 1\"}");
- if(DEBUG)
- printf( "audio loop\n" );
- control_cmd(channel, cmd);
- GetCmdValue(SPK_CONF, "system:hard_version", hversion, sizeof(hversion));
- if(strcmp(hversion, "Ver3.2") == 0)
- system("/etc/scripts/pa_mute.sh 0;echo 0 > /sys/class/gpio/gpio143/value");
- else
- system("/etc/scripts/pa_mute.sh 0;echo 0 > /sys/class/gpio/gpio134/value");
- BARESIP_STATUS = LOOPSTART;
- writeLog( FUN, "API Audio Loop", "Start" );
- }
- }
- void sipphone_loop_stop()
- {
- char cmd[MAX_PIPE_BUFSIZE], hversion[16];
- int channel = BARESIP_CHAN;
- if(DEBUG)
- printf( "BARESIP_STATUS [%d]\n", BARESIP_STATUS );
- if(BARESIP_STATUS == LOOPSTART)
- {
- strcpy(cmd,"{\"cmd\":\"auloop_stop\",\"data\":\"\"}");
- if(DEBUG)
- printf( "hangup call\n" );
- control_cmd(channel, cmd);
- GetCmdValue(SPK_CONF, "system:hard_version", hversion, sizeof(hversion));
- if(strcmp(hversion, "Ver3.2") == 0)
- system("/etc/scripts/pa_mute.sh 1;echo 1 > /sys/class/gpio/gpio143/value");
- else
- system("/etc/scripts/pa_mute.sh 1;echo 1 > /sys/class/gpio/gpio134/value");
- BARESIP_STATUS = IDLE;
- writeLog( FUN, "API Audio Loop", "Stop" );
- }
- }
- void *playTimer(void *arg)
- {
- char cmd[32];
- PlayInfo *p = arg;
- long t = p->duration*1000*1000;
- usleep(t);
- vlcInfo.state = FALSE;
- sprintf(cmd,"kill -9 %d",vlcInfo.pid);
- system(cmd);
- writeLog(FUN, "Specified duration expires", vlcInfo.param);
- }
- void *handle_playAudio(void *arg)
- {
- char syscmd[256];
- int status;
- PlayInfo *p = arg;
- if(strlen(p->url) > 7 && (strncmp(p->url, "http://", 7) == 0 || strncmp(p->url, "rtsp://", 7) == 0 || strncmp(p->url, "ftp://", 6) == 0))
- {
- if(p->volume >= 0)
- {
- sprintf(syscmd, "vlc -I dummy --network-caching=100 --gain=%.02f --play-and-exit '%s'", (float) p->volume/100, p->url);
- sprintf(vlcInfo.param,"URL: %s; valume: %d", p->url, p->volume);
- }
- else
- {
- sprintf(syscmd, "vlc -I dummy --network-caching=100 --gain=%.02f --play-and-exit '%s'", (float) p->volume/100, p->url);
- sprintf(vlcInfo.param,"URL: %s", p->url);
- }
- char *argv[] = {"sh","-c",syscmd, NULL};
- status = posix_spawn(&vlcInfo.pid,"/bin/sh",NULL,NULL,argv,NULL);
- if(status == 0)
- {
- vlcInfo.state = TRUE;
- amplifier_switch(TRUE);
- if(p->duration > 0)
- {
- pthread_t thread_audio;
- char strtmp[32];
- pthread_create(&thread_audio, NULL, playTimer, p);
- pthread_detach(thread_audio);
- sprintf(strtmp,"; duration: %ds", p->duration);
- strcat(vlcInfo.param, strtmp);
- }
- writeLog(FUN,"API Play URL Audio", vlcInfo.param);
- if(waitpid(vlcInfo.pid, &status, 0) != -1)
- {
- amplifier_switch(FALSE);
- printf("Child exited with status %i\n", status);
- if(vlcInfo.state)
- {
- writeLog(FUN, "Audio file playback ends", vlcInfo.param);
- vlcInfo.state = FALSE;
- }
- }
- }
- }
- free(p);
- }
- //gpio控制指令处理
- void ProcessAPIReply( redisReply * pReply )
- {
- cJSON *pJson = NULL, *subJson = NULL;
- redisReply * pSubReply = NULL;
- char cmd[MAX_PIPE_BUFSIZE], shellcmd[MAX_PIPE_BUFSIZE];
- char sipphone[8],relay[8],player[8],strtmp[64];
- int channel = BARESIP_CHAN;
- if ( pReply->elements == 2 )
- {
- pSubReply = pReply->element[1];
- if(DEBUG)
- printf( "Msg [%s]\n", pSubReply->str );
- pJson = cJSON_Parse(pSubReply->str);
- if ( pJson ) {
- if(cJSON_GetObjectItem(pJson, "type"))
- {
- if(strcmp(cJSON_GetObjectItem(pJson, "type")->valuestring, "sipphone") == 0)
- {
- GetCmdValue(SPK_CONF, "api:call_enable", sipphone, sizeof(sipphone));
- if(cJSON_GetObjectItem(pJson, "action")){
- if(strcmp(sipphone, "yes") == 0)
- {
- if(strcmp(cJSON_GetObjectItem(pJson, "action")->valuestring, "call") == 0)
- {
- if(cJSON_GetObjectItem(pJson, "data"))
- {
- subJson = cJSON_GetObjectItem(pJson, "data");
- sipphone_call(cJSON_GetObjectItem(subJson, "number")->valuestring, cJSON_GetObjectItem(subJson, "line")->valuestring);
- }
- }
- else if(strcmp(cJSON_GetObjectItem(pJson, "action")->valuestring, "answer") == 0)
- {
- sipphone_answer();
- }
- else if(strcmp(cJSON_GetObjectItem(pJson, "action")->valuestring, "hangup") == 0)
- {
- sipphone_hangup();
- }
-
- }
- if(strcmp(cJSON_GetObjectItem(pJson, "action")->valuestring, "auloopstart") == 0)
- {
- sipphone_loop_start();
- }
- else if(strcmp(cJSON_GetObjectItem(pJson, "action")->valuestring, "auloopstop") == 0)
- {
- sipphone_loop_stop();
- }
- }
- }
- else if(strcmp(cJSON_GetObjectItem(pJson, "type")->valuestring, "relay") == 0)
- {
- if(cJSON_GetObjectItem(pJson, "action"))
- {
- if(strcmp(cJSON_GetObjectItem(pJson, "action")->valuestring, "on") == 0)
- {
- outputControl(GPIO_RELAY, GPIO_ON);
- subJson = cJSON_GetObjectItem(pJson, "data");
- if(subJson){
- delay = cJSON_GetObjectItem(subJson, "duration")->valueint;
- if(delay > 0)
- {
- int ret_thrd_delay;
- pthread_t thread_delay;
- ret_thrd_delay = pthread_create(&thread_delay, NULL, gpioDelayControl, NULL);
- if (ret_thrd_delay != 0) {
- printf("create thread_delay gpioDelayControl failed\n");
- cJSON_Delete(pJson);
- return;
- }
- pthread_detach(thread_delay);
- }
- }
- }
- else if(strcmp(cJSON_GetObjectItem(pJson, "action")->valuestring, "off") == 0)
- {
- outputControl(GPIO_RELAY, GPIO_OFF);
- }
- }
- }
- else if(strcmp(cJSON_GetObjectItem(pJson, "type")->valuestring, "player") == 0)
- {
- if(cJSON_GetObjectItem(pJson, "action"))
- {
- if(strcmp(cJSON_GetObjectItem(pJson, "action")->valuestring, "start") == 0)
- {
- subJson = cJSON_GetObjectItem(pJson, "data");
- if(subJson && cJSON_GetObjectItem(subJson, "repeat") && cJSON_GetObjectItem(subJson, "volume"))
- {
- int repeat = cJSON_GetObjectItem(subJson, "repeat")->valueint;
- int volume = cJSON_GetObjectItem(subJson, "volume")->valueint;
- if(volume >= 0)
- {
- sprintf(cmd,"{\"cmd\":\"setaudiotempvol\",\"data\":\"%d\"}",volume);
- control_cmd(channel, cmd);
- }
- sprintf(cmd,"{\"cmd\":\"play\",\"data\":\"%s:%d\"}",cJSON_GetObjectItem(subJson, "file")->valuestring,repeat);
- control_cmd(channel, cmd);
- PLAYING = TRUE;
- sprintf(strtmp, "File: %s; Repeat: %d; Volume: %d", cJSON_GetObjectItem(subJson, "file")->valuestring, repeat, volume);
- writeLog( FUN, "API Play Auido", strtmp );
- }
- }
- else if(strcmp(cJSON_GetObjectItem(pJson, "action")->valuestring, "stop") == 0)
- {
- sprintf(cmd,"{\"cmd\":\"play\",\"data\":\"\"}");
- control_cmd(channel, cmd);
- PLAYING = FALSE;
- writeLog( FUN, "API Stop Auido", "" );
- }
- }
- }
- else if(strcmp(cJSON_GetObjectItem(pJson, "type")->valuestring, "urlplayer") == 0)
- {
- if(cJSON_GetObjectItem(pJson, "action"))
- {
- if(strcmp(cJSON_GetObjectItem(pJson, "action")->valuestring, "start") == 0)
- {
- subJson = cJSON_GetObjectItem(pJson, "data");
- if(subJson && cJSON_GetObjectItem(subJson, "duration") && cJSON_GetObjectItem(subJson, "volume"))
- {
- pthread_t thread_audio;
- int ret_thrd;
- PlayInfo *playAudioInfo = malloc(sizeof(PlayInfo));
- playAudioInfo->duration = cJSON_GetObjectItem(subJson, "duration")->valueint;
- playAudioInfo->volume = cJSON_GetObjectItem(subJson, "volume")->valueint;
- strcpy(playAudioInfo->url, cJSON_GetObjectItem(subJson, "url")->valuestring);
- ret_thrd = pthread_create(&thread_audio, NULL, handle_playAudio, playAudioInfo);
- if (ret_thrd != 0)
- {
- printf("create thread1 handle_playAudio failed\n");
- free(playAudioInfo);
- cJSON_Delete(pJson);
- return;
- }
- pthread_detach(thread_audio);
- }
- }
- else if(strcmp(cJSON_GetObjectItem(pJson, "action")->valuestring, "stop") == 0)
- {
- if(vlcInfo.state)
- {
- sprintf(cmd,"kill -9 %d",vlcInfo.pid);
- system(cmd);
- vlcInfo.state = FALSE;
- writeLog(FUN, "Playback stops by API call", vlcInfo.param);
- }
- }
- }
- }
- }
- }else{
- printf( "parse failed!\n");
- }
- if(pJson != NULL) cJSON_Delete(pJson);
- }
- }
- /*
- * 接收控制指令.
- */
- void *api_control()
- {
- redisContext * pContext = redisConnectUnix(unix_socket_path);
- if ( NULL == pContext || pContext->err == 1 )
- {
- printf( "%s\n", pContext->errstr );
- exit( -1 );
- }
- char * pKey = "api-channel";
- redisReply * pReply;
- while(1){
- pReply = NULL;
- pReply = redisCommand( pContext, "BRPOP %s 60", pKey );
- if(pReply != NULL && pReply->type == REDIS_REPLY_ARRAY){
- ProcessAPIReply( pReply );
- }
- if(pReply != NULL) freeReplyObject( pReply );
- }
- redisFree( pContext );
- }
- //解析音量设置数据
- void ProcessVolumeReply( redisReply * pReply )
- {
- cJSON *pJson = NULL;
- redisReply * pSubReply = NULL;
- char cmd[MAX_PIPE_BUFSIZE];
- int channel = BARESIP_CHAN;
- if ( pReply != NULL && pReply->elements == 3 )
- {
- pSubReply = pReply->element[2];
- pJson = cJSON_Parse(pSubReply->str);
- if ( pJson ) {
- if(cJSON_GetObjectItem(pJson, "sip_volume"))
- {
- sprintf(cmd,"{\"cmd\":\"setvol\",\"data\":\"%d\"}",cJSON_GetObjectItem(pJson, "sip_volume")->valueint);
- control_cmd(channel, cmd);
- }
- }else{
- printf( "parse failed!\n");
- }
- if(pJson != NULL) cJSON_Delete(pJson);
- }
- }
- /*
- * 订阅音量信息.
- */
- void *get_volume_info()
- {
- redisContext * pContext = redisConnectUnix(unix_socket_path);
- if ( NULL == pContext || pContext->err == 1 )
- {
- printf( "%s\n", pContext->errstr );
- exit( -1 );
- }
- char * pKey = "volume-value-channel";
- redisReply * pReply = redisCommand( pContext, "SUBSCRIBE %s", pKey );
- freeReplyObject( pReply );
- while ( redisGetReply( pContext, (void **)&pReply ) == REDIS_OK )
- {
- ProcessVolumeReply( pReply );
- freeReplyObject( pReply );
- }
- redisFree( pContext );
- }
- int main(int argc, char *argv[]){
- char model[16];
- int ret_thrd1,ret_thrd2;
- pthread_t thread1, thread2;
- if(argc == 2 && strcmp(argv[1], "debug") == 0)
- DEBUG = TRUE;
- redisClient = create_redis_client(unix_socket_path);
- //启动线程订阅BARESIP实时状态
- ret_thrd1 = pthread_create(&thread1, NULL, baresip_status, NULL);
- if (ret_thrd1 != 0) {
- printf("create thread1 baresip_status failed\n");
- return 0;
- }
- //启动线程订阅音量设置
- ret_thrd2 = pthread_create(&thread2, NULL, get_volume_info, NULL);
- if (ret_thrd2 != 0) {
- printf("create thread2 get_volume_info failed\n");
- return 0;
- }
- api_control();
- }
|