main.c 41 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231
  1. #include <sys/poll.h>
  2. #include <string.h>
  3. #include <stdio.h>
  4. #include <stdlib.h>
  5. #include <sys/types.h>
  6. #include <sys/wait.h>
  7. #include <spawn.h>
  8. #include <unistd.h>
  9. #include <fcntl.h>
  10. #include <assert.h>
  11. #include <time.h>
  12. #include <pthread.h>
  13. #include "hiredis/hiredis.h"
  14. #include "cjson/cJSON.h"
  15. #include "iniparser/iniparser.h"
  16. #define Boolean int
  17. #define TRUE 1
  18. #define FALSE 0
  19. #define MAX_PIPE_BUFSIZE 256
  20. //BARESIP_STATUS
  21. #define IDLE 0
  22. #define INUSE 1
  23. #define RING 2
  24. #define RINGING 3
  25. #define HOLD 4
  26. #define OFFLINE 5
  27. #define DIALING 6
  28. #define LOOPSTART 7
  29. //BARESIP_REG
  30. #define REGISTER_FAIL 0
  31. #define REGISTER_OK 1
  32. //REDIS_CHANNEL
  33. #define BARESIP_CHAN 0
  34. #define GPIO_CHAN 1
  35. //GPIO_STATUS
  36. #define GPIO_OFF 0
  37. #define GPIO_ON 1
  38. #define SPK_CONF "/etc/speaker.conf"
  39. #define unix_socket_path "/tmp/redis.sock"
  40. //operator log type
  41. #define BTN "BUTTON"
  42. #define FUN "FUNCTION"
  43. #define STA "SIP STATE"
  44. #define GPIO_RELAY "gpio67"
  45. #define VAR_IP "${ip}"
  46. #define VAR_MAC "${mac}"
  47. #define VAR_UA "${ua}"
  48. #define VAR_NUM "${number}"
  49. struct VLC_INFO{
  50. Boolean state;
  51. pid_t pid;
  52. char param[256];
  53. };
  54. typedef struct _playInfo{
  55. int duration;
  56. int volume;
  57. char url[128];
  58. } PlayInfo;
  59. typedef struct {
  60. redisContext *context;
  61. const char *socket_path;
  62. time_t last_activity;
  63. } redis_client_t;
  64. static int BARESIP_STATUS = OFFLINE;
  65. static int DEBUG = FALSE;
  66. static int ACCOUNT1_REG = REGISTER_FAIL;
  67. static int ACCOUNT2_REG = REGISTER_FAIL;
  68. static int ACCOUNT3_REG = REGISTER_FAIL;
  69. static int ACCOUNTP2P_REG = REGISTER_FAIL;
  70. static int PLAYING = FALSE;
  71. static int delay = 0;
  72. struct VLC_INFO vlcInfo;
  73. static redis_client_t *redisClient;
  74. redis_client_t* create_redis_client(const char *socket_path) {
  75. redis_client_t *client = malloc(sizeof(redis_client_t));
  76. client->socket_path = socket_path;
  77. client->context = redisConnectUnix(socket_path);
  78. client->last_activity = time(NULL);
  79. return client;
  80. }
  81. int ensure_connected(redis_client_t *client) {
  82. if (client->context == NULL || client->context->err) {
  83. if (client->context) {
  84. redisFree(client->context);
  85. }
  86. client->context = redisConnectUnix(client->socket_path);
  87. if (client->context == NULL || client->context->err) {
  88. return -1; // 连接失败
  89. }
  90. }
  91. client->last_activity = time(NULL);
  92. return 0;
  93. }
  94. void redis_command_safe(const char *format, char *value) {
  95. if (ensure_connected(redisClient) == 0) {
  96. redisReply *reply = redisCommand(redisClient->context, format, value);
  97. if (reply) {
  98. // 处理回复
  99. freeReplyObject(reply);
  100. }
  101. }
  102. }
  103. /*
  104. * @cmd 执行命令
  105. * @value 命令结果指针
  106. * @lenth 存储结果长度
  107. int GetCmdValue(char *cmd, char *value, int lenth)
  108. {
  109. bzero(value, lenth);
  110. FILE *fp = popen(cmd,"r");
  111. if(fp != NULL){
  112. fread(value, 1, lenth, fp);
  113. pclose(fp);
  114. } else {
  115. printf("Handle \"%s\" failed.\n", cmd);
  116. return FALSE;
  117. }
  118. return TRUE;
  119. }
  120. */
  121. int GetCmdValue(char *file, char *key, char *value, int lenth)
  122. {
  123. dictionary * ini ;
  124. ini = iniparser_load(file);
  125. if (ini==NULL) {
  126. fprintf(stderr, "cannot parse file: %s\n", file);
  127. return FALSE ;
  128. }
  129. strcpy(value, iniparser_getstring(ini, key, ""));
  130. if(DEBUG)
  131. printf("keystr: \"%s\" ; value: %s.\n", key, value);
  132. iniparser_freedict(ini);
  133. return TRUE;
  134. }
  135. void writeLog(char *type,char *action, char *remark)
  136. {
  137. char logstr[256];
  138. sprintf(logstr, "%s,%s,%s", type, action, remark);
  139. redis_command_safe("LPUSH writelog-channel %s", logstr);
  140. }
  141. char *strrpl(char *s, const char *s1, const char *s2)
  142. {
  143. char *ptr;
  144. while (ptr = strstr(s, s1)) /* 如果在s中找到s1 */
  145. {
  146. memmove(ptr + strlen(s2) , ptr + strlen(s1), strlen(ptr) - strlen(s1) + 1);
  147. memcpy(ptr, &s2[0], strlen(s2));
  148. }
  149. return s;
  150. }
  151. //控制功放的开启/关闭,TRUE/FALSE
  152. void amplifier_switch(Boolean enable){
  153. if(enable)
  154. {
  155. system("/etc/scripts/pa_mute.sh 0");
  156. }
  157. else
  158. {
  159. system("/etc/scripts/pa_mute.sh 1");
  160. }
  161. }
  162. Boolean get_ip(char * pv)
  163. {
  164. FILE * fp;
  165. char cmdbuf[128], value[32];
  166. char *tmp=NULL;
  167. sprintf(cmdbuf,"/sbin/ifconfig eth0 | grep inet | cut -d\":\" -f2 | cut -d\" \" -f1");
  168. fp = popen(cmdbuf, "r");
  169. if (fp == NULL) {
  170. // printf("Fail to open pipe\n");
  171. return FALSE;
  172. }
  173. memset(value,0,sizeof(value));
  174. if (!feof(fp) && fgets(value,32,fp) != NULL)
  175. ;
  176. // printf("value:%s\n", value);
  177. else {
  178. printf("ip wrong\n");
  179. return FALSE;
  180. }
  181. pclose(fp);
  182. if(strlen(value) < 10)
  183. return FALSE;
  184. if(tmp = strstr(value,"\n"))
  185. {
  186. *tmp = '\0';
  187. }
  188. strcpy(pv,value);
  189. return TRUE;
  190. }
  191. Boolean get_mac(char * pv)
  192. {
  193. FILE * fp;
  194. char cmdbuf[128], value[32];
  195. char *tmp=NULL;
  196. sprintf(cmdbuf,"ifconfig eth0 | grep HWaddr | tr -d : | awk '{print $5}'");
  197. fp = popen(cmdbuf, "r");
  198. if (fp == NULL) {
  199. // printf("Fail to open pipe\n");
  200. return FALSE;
  201. }
  202. memset(value,0,sizeof(value));
  203. if (!feof(fp) && fgets(value,32,fp) != NULL)
  204. ;
  205. // printf("value:%s\n", value);
  206. else {
  207. printf("ip wrong\n");
  208. return FALSE;
  209. }
  210. pclose(fp);
  211. if(strlen(value) < 10)
  212. return FALSE;
  213. if(tmp = strstr(value,"\n"))
  214. {
  215. *tmp = '\0';
  216. }
  217. strcpy(pv,value);
  218. return TRUE;
  219. }
  220. void action_url(char *url)
  221. {
  222. char cmd[320];
  223. sprintf(cmd,"curl -k --connect-timeout 5 '%s' 2>/dev/null &",url);
  224. if(DEBUG)
  225. printf( "Command: %s\n", cmd);
  226. system(cmd);
  227. writeLog( FUN, "API HTTP Request", url );
  228. }
  229. //发送控制指令
  230. void control_cmd(int channel, char *cmd)
  231. {
  232. char redisCmd[256];
  233. switch (channel)
  234. {
  235. case BARESIP_CHAN:
  236. if(DEBUG)
  237. printf( "control-channel [%s]\n", cmd );
  238. redis_command_safe("LPUSH control-channel %s", cmd );
  239. break;
  240. case GPIO_CHAN:
  241. if(DEBUG)
  242. printf( "output-channel [%s]\n", cmd );
  243. redis_command_safe("LPUSH output-channel %s", cmd );
  244. break;
  245. default:
  246. redis_command_safe("LPUSH control-channel %s", cmd );
  247. break;
  248. }
  249. }
  250. void outputControl(char *id, int enable){
  251. char cmd[64];
  252. int channel = GPIO_CHAN;
  253. if(enable){
  254. char output_type[32];
  255. GetCmdValue(SPK_CONF, "relay_ctrl:type", output_type, sizeof(output_type));
  256. sprintf(cmd,"{\"id\":\"%s\",\"type\":\"%s\"}",id,output_type);
  257. control_cmd(channel,cmd);
  258. }
  259. else
  260. {
  261. sprintf(cmd,"{\"id\":\"%s\",\"type\":\"Off\"}",id);
  262. control_cmd(channel,cmd);
  263. }
  264. }
  265. //gpio延时控制
  266. void *gpioDelayControl()
  267. {
  268. usleep(delay*1000*1000);
  269. outputControl(GPIO_RELAY, GPIO_OFF);
  270. if(DEBUG)
  271. printf( "gpio135 set off\n" );
  272. }
  273. //呼入触发
  274. void incomingTrigger(cJSON *pJson)
  275. {
  276. char enable[8],url[256],ipaddr[16],macaddr[16], peeruri[128];
  277. GetCmdValue(SPK_CONF, "call_action_url:incoming_enable", enable, sizeof(enable));
  278. if(strcmp(enable,"yes") == 0)
  279. {
  280. GetCmdValue(SPK_CONF, "call_action_url:incoming_url", url, sizeof(url));
  281. if(strstr(url,VAR_IP))
  282. {
  283. if(get_ip(ipaddr))
  284. strcpy(url, strrpl(url, VAR_IP, ipaddr));
  285. }
  286. if(strstr(url,VAR_MAC))
  287. {
  288. if(get_mac(macaddr))
  289. strcpy(url, strrpl(url, VAR_MAC, macaddr));
  290. }
  291. if(strstr(url,VAR_UA))
  292. {
  293. strcpy(url, strrpl(url, VAR_UA, cJSON_GetObjectItem(pJson, "exten")->valuestring));
  294. }
  295. if(strstr(url,VAR_NUM))
  296. {
  297. char *ret, number[64];
  298. strcpy(peeruri, cJSON_GetObjectItem(pJson, "peeruri")->valuestring);
  299. ret = strchr(peeruri, '@');
  300. if(ret)
  301. {
  302. memset(number,0,sizeof(number));
  303. strncpy(number,peeruri,ret - peeruri);
  304. strcpy(url, strrpl(url, VAR_NUM, number + 4));
  305. }
  306. }
  307. action_url(url);
  308. }
  309. }
  310. //呼出触发
  311. void outgoingTrigger(cJSON *pJson)
  312. {
  313. char enable[8],url[256],ipaddr[16],macaddr[16], peeruri[128];
  314. GetCmdValue(SPK_CONF, "call_action_url:outgoing_enable", enable, sizeof(enable));
  315. if(strcmp(enable,"yes") == 0)
  316. {
  317. GetCmdValue(SPK_CONF, "call_action_url:outgoing_url", url, sizeof(url));
  318. if(strstr(url,VAR_IP))
  319. {
  320. if(get_ip(ipaddr))
  321. strcpy(url, strrpl(url, VAR_IP, ipaddr));
  322. }
  323. if(strstr(url,VAR_MAC))
  324. {
  325. if(get_mac(macaddr))
  326. strcpy(url, strrpl(url, VAR_MAC, macaddr));
  327. }
  328. if(strstr(url,VAR_UA))
  329. {
  330. strcpy(url, strrpl(url, VAR_UA, cJSON_GetObjectItem(pJson, "exten")->valuestring));
  331. }
  332. if(strstr(url,VAR_NUM))
  333. {
  334. char *ret, number[64];
  335. strcpy(peeruri, cJSON_GetObjectItem(pJson, "peeruri")->valuestring);
  336. ret = strchr(peeruri, '@');
  337. if(ret)
  338. {
  339. memset(number,0,sizeof(number));
  340. strncpy(number,peeruri,ret - peeruri);
  341. strcpy(url, strrpl(url, VAR_NUM, number + 4));
  342. }
  343. }
  344. action_url(url);
  345. }
  346. }
  347. //应答触发
  348. void answeredTrigger(cJSON *pJson)
  349. {
  350. char enable[8],url[256],ipaddr[16],macaddr[16], peeruri[128];
  351. GetCmdValue(SPK_CONF, "call_action_url:answered_enable", enable, sizeof(enable));
  352. if(strcmp(enable,"yes") == 0)
  353. {
  354. GetCmdValue(SPK_CONF, "call_action_url:answered_url", url, sizeof(url));
  355. if(strstr(url,VAR_IP))
  356. {
  357. if(get_ip(ipaddr))
  358. strcpy(url, strrpl(url, VAR_IP, ipaddr));
  359. }
  360. if(strstr(url,VAR_MAC))
  361. {
  362. if(get_mac(macaddr))
  363. strcpy(url, strrpl(url, VAR_MAC, macaddr));
  364. }
  365. if(strstr(url,VAR_UA))
  366. {
  367. strcpy(url, strrpl(url, VAR_UA, cJSON_GetObjectItem(pJson, "exten")->valuestring));
  368. }
  369. if(strstr(url,VAR_NUM))
  370. {
  371. char *ret, number[64];
  372. strcpy(peeruri, cJSON_GetObjectItem(pJson, "peeruri")->valuestring);
  373. ret = strchr(peeruri, '@');
  374. if(ret)
  375. {
  376. memset(number,0,sizeof(number));
  377. strncpy(number,peeruri,ret - peeruri);
  378. strcpy(url, strrpl(url, VAR_NUM, number + 4));
  379. }
  380. }
  381. action_url(url);
  382. }
  383. }
  384. //应答触发
  385. void hangupTrigger(cJSON *pJson)
  386. {
  387. char enable[8],url[256],ipaddr[16],macaddr[16], peeruri[128];
  388. GetCmdValue(SPK_CONF, "call_action_url:hangup_enable", enable, sizeof(enable));
  389. if(strcmp(enable,"yes") == 0)
  390. {
  391. GetCmdValue(SPK_CONF, "call_action_url:hangup_url", url, sizeof(url));
  392. if(strstr(url,VAR_IP))
  393. {
  394. if(get_ip(ipaddr))
  395. strcpy(url, strrpl(url, VAR_IP, ipaddr));
  396. }
  397. if(strstr(url,VAR_MAC))
  398. {
  399. if(get_mac(macaddr))
  400. strcpy(url, strrpl(url, VAR_MAC, macaddr));
  401. }
  402. if(strstr(url,VAR_UA))
  403. {
  404. strcpy(url, strrpl(url, VAR_UA, cJSON_GetObjectItem(pJson, "exten")->valuestring));
  405. }
  406. if(strstr(url,VAR_NUM))
  407. {
  408. char *ret, number[64];
  409. strcpy(peeruri, cJSON_GetObjectItem(pJson, "peeruri")->valuestring);
  410. ret = strchr(peeruri, '@');
  411. if(ret)
  412. {
  413. memset(number,0,sizeof(number));
  414. strncpy(number,peeruri,ret - peeruri);
  415. strcpy(url, strrpl(url, VAR_NUM, number + 4));
  416. }
  417. }
  418. action_url(url);
  419. }
  420. }
  421. //baresip状态监控
  422. void ProcessReply( redisReply * pReply )
  423. {
  424. cJSON *pJson = NULL;
  425. redisReply * pSubReply = NULL;
  426. if ( pReply != NULL && pReply->elements == 3 )
  427. {
  428. pSubReply = pReply->element[2];
  429. if(DEBUG)
  430. printf( "Msg [%s]\n", pSubReply->str );
  431. pJson = cJSON_Parse(pSubReply->str);
  432. if ( pJson ) {
  433. if(strcmp(cJSON_GetObjectItem(pJson, "type")->valuestring, "CALL_ESTABLISHED") == 0)
  434. {
  435. //通话
  436. BARESIP_STATUS = INUSE;
  437. answeredTrigger(pJson);
  438. }
  439. else if(strcmp(cJSON_GetObjectItem(pJson, "direction")->valuestring, "incoming") == 0 &&
  440. strcmp(cJSON_GetObjectItem(pJson, "type")->valuestring, "CALL_CLOSED") == 0)
  441. {
  442. //挂断
  443. if(BARESIP_STATUS != OFFLINE){
  444. BARESIP_STATUS = IDLE;
  445. }
  446. hangupTrigger(pJson);
  447. }
  448. else if(strcmp(cJSON_GetObjectItem(pJson, "direction")->valuestring, "outgoing") == 0 &&
  449. strcmp(cJSON_GetObjectItem(pJson, "type")->valuestring, "CALL_CLOSED") == 0)
  450. {
  451. //挂断
  452. if(BARESIP_STATUS != OFFLINE){
  453. BARESIP_STATUS = IDLE;
  454. }
  455. hangupTrigger(pJson);
  456. }
  457. else if(strcmp(cJSON_GetObjectItem(pJson, "direction")->valuestring, "incoming") == 0 &&
  458. strcmp(cJSON_GetObjectItem(pJson, "type")->valuestring, "CALL_INCOMING") == 0)
  459. {
  460. //呼入振铃状态
  461. if(BARESIP_STATUS == IDLE)
  462. {
  463. BARESIP_STATUS = RING;
  464. incomingTrigger(pJson);
  465. }
  466. }
  467. else if(strcmp(cJSON_GetObjectItem(pJson, "direction")->valuestring, "outgoing") == 0 &&
  468. strcmp(cJSON_GetObjectItem(pJson, "type")->valuestring, "CALL_OUTGOING") == 0)
  469. {
  470. //呼出回铃状态
  471. if(BARESIP_STATUS == IDLE || BARESIP_STATUS == DIALING)
  472. {
  473. BARESIP_STATUS = RINGING;
  474. outgoingTrigger(pJson);
  475. }
  476. }
  477. else if(strcmp(cJSON_GetObjectItem(pJson, "type")->valuestring, "REGISTER_OK") == 0)
  478. {
  479. //如果是注册成功点亮指示灯
  480. char enac1[8],enac2[8],enac3[8],accountaor1[192], accountaor2[192], accountaor3[192];
  481. char account1[32], domain1[128], account2[32], domain2[128], account3[32], domain3[128];
  482. if(BARESIP_STATUS == OFFLINE || BARESIP_STATUS == DIALING)
  483. {
  484. BARESIP_STATUS = IDLE;
  485. }
  486. if(cJSON_GetObjectItem(pJson, "accountaor") != NULL)
  487. {
  488. GetCmdValue(SPK_CONF, "account_info_1:enable", enac1, sizeof(enac1));
  489. if(strcmp(enac1, "yes") == 0 && ACCOUNT1_REG == REGISTER_FAIL)
  490. {
  491. GetCmdValue(SPK_CONF, "account_info_1:username", account1, sizeof(account1));
  492. GetCmdValue(SPK_CONF, "account_info_1:domain", domain1, sizeof(domain1));
  493. if(strlen(domain1) == 0)
  494. {
  495. GetCmdValue(SPK_CONF, "account_info_1:server", domain1, sizeof(domain1));
  496. }
  497. memset(accountaor1, '\0', sizeof(accountaor1));
  498. sprintf(accountaor1, "sip:%s@%s", account1, domain1);
  499. if (strcmp(cJSON_GetObjectItem(pJson, "accountaor")->valuestring, accountaor1) == 0)
  500. {
  501. ACCOUNT1_REG = REGISTER_OK;
  502. cJSON_Delete(pJson);
  503. return;
  504. }
  505. }
  506. GetCmdValue(SPK_CONF, "account_info_2:enable", enac2, sizeof(enac2));
  507. if(strcmp(enac2, "yes") == 0 && ACCOUNT2_REG == REGISTER_FAIL)
  508. {
  509. GetCmdValue(SPK_CONF, "account_info_2:username", account2, sizeof(account2));
  510. GetCmdValue(SPK_CONF, "account_info_2:domain", domain2, sizeof(domain2));
  511. if(strlen(domain2) == 0)
  512. {
  513. GetCmdValue(SPK_CONF, "account_info_2:server", domain2, sizeof(domain2));
  514. }
  515. memset(accountaor2, '\0', sizeof(accountaor2));
  516. sprintf(accountaor2, "sip:%s@%s", account2, domain2);
  517. if (strcmp(cJSON_GetObjectItem(pJson, "accountaor")->valuestring, accountaor2) == 0)
  518. {
  519. ACCOUNT2_REG = REGISTER_OK;
  520. cJSON_Delete(pJson);
  521. return;
  522. }
  523. }
  524. GetCmdValue(SPK_CONF, "account_info_3:enable", enac3, sizeof(enac3));
  525. if(strcmp(enac3, "yes") == 0 && ACCOUNT3_REG == REGISTER_FAIL)
  526. {
  527. GetCmdValue(SPK_CONF, "account_info_3:username", account3, sizeof(account3));
  528. GetCmdValue(SPK_CONF, "account_info_3:domain", domain3, sizeof(domain3));
  529. if(strlen(domain3) == 0)
  530. {
  531. GetCmdValue(SPK_CONF, "account_info_3:server", domain3, sizeof(domain3));
  532. }
  533. memset(accountaor3, '\0', sizeof(accountaor3));
  534. sprintf(accountaor3, "sip:%s@%s", account3, domain3);
  535. if (strcmp(cJSON_GetObjectItem(pJson, "accountaor")->valuestring, accountaor3) == 0)
  536. {
  537. ACCOUNT3_REG = REGISTER_OK;
  538. cJSON_Delete(pJson);
  539. return;
  540. }
  541. }
  542. }
  543. }
  544. else if(strcmp(cJSON_GetObjectItem(pJson, "type")->valuestring, "REGISTER_FAIL") == 0 )
  545. {
  546. char enac1[8],enac2[8],enac3[8],accountaor1[192], accountaor2[192], accountaor3[192];
  547. char account1[32], domain1[128], account2[32], domain2[128], account3[32], domain3[128];
  548. if(cJSON_GetObjectItem(pJson, "accountaor") != NULL)
  549. {
  550. GetCmdValue(SPK_CONF, "account_info_1:enable", enac1, sizeof(enac1));
  551. if(strcmp(enac1, "yes") == 0 && ACCOUNT1_REG == REGISTER_OK)
  552. {
  553. GetCmdValue(SPK_CONF, "account_info_1:username", account1, sizeof(account1));
  554. GetCmdValue(SPK_CONF, "account_info_1:domain", domain1, sizeof(domain1));
  555. if(strlen(domain1) == 0)
  556. {
  557. GetCmdValue(SPK_CONF, "account_info_1:server", domain1, sizeof(domain1));
  558. }
  559. memset(accountaor1, '\0', sizeof(accountaor1));
  560. sprintf(accountaor1, "sip:%s@%s", account1, domain1);
  561. if (strcmp(cJSON_GetObjectItem(pJson, "accountaor")->valuestring, accountaor1) == 0)
  562. {
  563. ACCOUNT1_REG = REGISTER_FAIL;
  564. if( ACCOUNT2_REG == REGISTER_FAIL && ACCOUNT3_REG == REGISTER_FAIL && ACCOUNTP2P_REG == REGISTER_FAIL ){
  565. BARESIP_STATUS = OFFLINE;
  566. }
  567. cJSON_Delete(pJson);
  568. return;
  569. }
  570. }
  571. GetCmdValue(SPK_CONF, "account_info_2:enable", enac2, sizeof(enac2));
  572. if(strcmp(enac2, "yes") == 0 && ACCOUNT2_REG == REGISTER_OK)
  573. {
  574. GetCmdValue(SPK_CONF, "account_info_2:username", account2, sizeof(account2));
  575. GetCmdValue(SPK_CONF, "account_info_2:domain", domain2, sizeof(domain2));
  576. if(strlen(domain2) == 0)
  577. {
  578. GetCmdValue(SPK_CONF, "account_info_2:server", domain2, sizeof(domain2));
  579. }
  580. memset(accountaor2, '\0', sizeof(accountaor2));
  581. sprintf(accountaor2, "sip:%s@%s", account2, domain2);
  582. if (strcmp(cJSON_GetObjectItem(pJson, "accountaor")->valuestring, accountaor2) == 0)
  583. {
  584. ACCOUNT2_REG = REGISTER_FAIL;
  585. if( ACCOUNT1_REG == REGISTER_FAIL && ACCOUNT3_REG == REGISTER_FAIL && ACCOUNTP2P_REG == REGISTER_FAIL ){
  586. BARESIP_STATUS = OFFLINE;
  587. }
  588. cJSON_Delete(pJson);
  589. return;
  590. }
  591. }
  592. GetCmdValue(SPK_CONF, "account_info_3:enable", enac3, sizeof(enac3));
  593. if(strcmp(enac3, "yes") == 0 && ACCOUNT3_REG == REGISTER_OK)
  594. {
  595. GetCmdValue(SPK_CONF, "account_info_3:username", account3, sizeof(account3));
  596. GetCmdValue(SPK_CONF, "account_info_3:domain", domain3, sizeof(domain3));
  597. if(strlen(domain3) == 0)
  598. {
  599. GetCmdValue(SPK_CONF, "account_info_3:server", domain3, sizeof(domain3));
  600. }
  601. memset(accountaor3, '\0', sizeof(accountaor3));
  602. sprintf(accountaor3, "sip:%s@%s", account3, domain3);
  603. if (strcmp(cJSON_GetObjectItem(pJson, "accountaor")->valuestring, accountaor3) == 0)
  604. {
  605. ACCOUNT3_REG = REGISTER_FAIL;
  606. if( ACCOUNT1_REG == REGISTER_FAIL && ACCOUNT2_REG == REGISTER_FAIL && ACCOUNTP2P_REG == REGISTER_FAIL ){
  607. BARESIP_STATUS = OFFLINE;
  608. }
  609. cJSON_Delete(pJson);
  610. return;
  611. }
  612. }
  613. }
  614. }
  615. else if(strcmp(cJSON_GetObjectItem(pJson, "type")->valuestring, "EXIT") == 0)
  616. {
  617. BARESIP_STATUS = OFFLINE;
  618. ACCOUNT1_REG = REGISTER_FAIL;
  619. ACCOUNT2_REG = REGISTER_FAIL;
  620. ACCOUNT3_REG = REGISTER_FAIL;
  621. }
  622. else if(cJSON_GetObjectItem(pJson, "event")->type == 1 && cJSON_GetObjectItem(pJson, "event")->valueint == 0){
  623. if(strncmp(cJSON_GetObjectItem(pJson, "data")->valuestring,"\n--- User Agents",16) == 0)
  624. {
  625. char p2penable[8];
  626. GetCmdValue(SPK_CONF, "account_info_p2p:enable", p2penable, sizeof(p2penable));
  627. if(strcmp(p2penable,"yes") == 0)
  628. {
  629. ACCOUNTP2P_REG = REGISTER_OK;
  630. BARESIP_STATUS = IDLE;
  631. }
  632. else
  633. {
  634. ACCOUNTP2P_REG = REGISTER_FAIL;
  635. }
  636. }
  637. }
  638. if(DEBUG)
  639. printf( "Baresip Status is: %d\n", BARESIP_STATUS );
  640. }else{
  641. printf( "parse failed!\n");
  642. }
  643. if(pJson != NULL) cJSON_Delete(pJson);
  644. }
  645. }
  646. /*
  647. * 订阅baresip实时状态.
  648. */
  649. void *baresip_status()
  650. {
  651. redisContext * pContext = redisConnectUnix(unix_socket_path);
  652. if ( NULL == pContext || pContext->err == 1 )
  653. {
  654. printf( "%s\n", pContext->errstr );
  655. exit( -1 );
  656. }
  657. char * pKey = "session-channel";
  658. redisReply * pReply = redisCommand( pContext, "SUBSCRIBE %s", pKey );
  659. freeReplyObject( pReply );
  660. while ( redisGetReply( pContext, (void **)&pReply ) == REDIS_OK )
  661. {
  662. ProcessReply( pReply );
  663. freeReplyObject( pReply );
  664. }
  665. redisFree( pContext );
  666. }
  667. int get_line(int * line_id)
  668. {
  669. char enac[8], strtmp[32];
  670. int id = 0;
  671. memset(line_id,-1,sizeof(line_id));
  672. for(int i = 1; i < 4;i ++)
  673. {
  674. bzero(strtmp, sizeof(strtmp));
  675. sprintf(strtmp,"account_info_%d:enable",i);
  676. GetCmdValue(SPK_CONF, strtmp, enac, sizeof(enac));
  677. if(strcmp(enac,"yes") == 0)
  678. {
  679. line_id[i] = id;
  680. id ++;
  681. }
  682. }
  683. return TRUE;
  684. }
  685. void sipphone_call(char *number, char *line)
  686. {
  687. char cmd[MAX_PIPE_BUFSIZE];
  688. char accountaor[192],strtmp[64];
  689. char account[32],domain[128];
  690. int channel = BARESIP_CHAN, line_id[4];
  691. if(DEBUG)
  692. printf( "BARESIP_STATUS [%d]\n", BARESIP_STATUS );
  693. if(BARESIP_STATUS == IDLE)
  694. {
  695. BARESIP_STATUS = DIALING;
  696. if(strlen(number) == 0)
  697. {
  698. BARESIP_STATUS = IDLE;
  699. return;
  700. }
  701. get_line(line_id);
  702. if(strcmp(line,"auto") == 0)
  703. {
  704. if(DEBUG)
  705. printf("ACCOUNT1 is %d, ACCOUNT2 is %d, ACCOUNT3 is %d\n",ACCOUNT1_REG,ACCOUNT2_REG,ACCOUNT3_REG);
  706. if(ACCOUNT1_REG == REGISTER_OK)
  707. {
  708. if(line_id[1] == -1)
  709. {
  710. BARESIP_STATUS = IDLE;
  711. return;
  712. }
  713. sprintf(cmd,"{\"cmd\":\"dial\",\"data\":\"%s %d\"}",number, line_id[1]);
  714. }
  715. else if(ACCOUNT2_REG == REGISTER_OK)
  716. {
  717. if(line_id[2] == -1)
  718. {
  719. BARESIP_STATUS = IDLE;
  720. return;
  721. }
  722. sprintf(cmd,"{\"cmd\":\"dial\",\"data\":\"%s %d\"}",number, line_id[2]);
  723. }
  724. else if(ACCOUNT3_REG == REGISTER_OK)
  725. {
  726. if(line_id[3] == -1)
  727. {
  728. BARESIP_STATUS = IDLE;
  729. return;
  730. }
  731. sprintf(cmd,"{\"cmd\":\"dial\",\"data\":\"%s %d\"}",number, line_id[3]);
  732. }
  733. else
  734. {
  735. BARESIP_STATUS = IDLE;
  736. return;
  737. }
  738. }
  739. else if (strcmp(line, "account_info_1") == 0)
  740. {
  741. if(line_id[1] == -1 || ACCOUNT1_REG != REGISTER_OK)
  742. {
  743. BARESIP_STATUS = IDLE;
  744. return;
  745. }
  746. sprintf(cmd,"{\"cmd\":\"dial\",\"data\":\"%s %d\"}",number, line_id[1]);
  747. }
  748. else if (strcmp(line, "account_info_2") == 0)
  749. {
  750. if(line_id[2] == -1 || ACCOUNT2_REG != REGISTER_OK)
  751. {
  752. BARESIP_STATUS = IDLE;
  753. return;
  754. }
  755. sprintf(cmd,"{\"cmd\":\"dial\",\"data\":\"%s %d\"}",number, line_id[2]);
  756. }
  757. else if (strcmp(line, "account_info_3") == 0)
  758. {
  759. if(line_id[3] == -1 || ACCOUNT3_REG != REGISTER_OK)
  760. {
  761. BARESIP_STATUS = IDLE;
  762. return;
  763. }
  764. sprintf(cmd,"{\"cmd\":\"dial\",\"data\":\"%s %d\"}",number, line_id[3]);
  765. }
  766. else if(strcmp(line,"p2p") == 0)
  767. {
  768. sprintf(cmd,"{\"cmd\":\"dial\",\"data\":\"%s\"}",number);
  769. }
  770. if(DEBUG)
  771. printf( "dial [%s]\n", cmd );
  772. control_cmd(channel, cmd);
  773. sprintf(strtmp, "%s <%s>", number, line);
  774. writeLog( FUN, "API Call", strtmp );
  775. }
  776. }
  777. void sipphone_answer()
  778. {
  779. char cmd[MAX_PIPE_BUFSIZE];
  780. int channel = BARESIP_CHAN;
  781. if(DEBUG)
  782. printf( "BARESIP_STATUS [%d]\n", BARESIP_STATUS );
  783. if(BARESIP_STATUS == RING)
  784. {
  785. strcpy(cmd,"{\"cmd\":\"accept\",\"data\":\"\"}");
  786. if(DEBUG)
  787. printf( "answer call\n" );
  788. control_cmd(channel, cmd);
  789. writeLog( FUN, "API Answer", "" );
  790. }
  791. }
  792. void sipphone_hangup()
  793. {
  794. char cmd[MAX_PIPE_BUFSIZE];
  795. int channel = BARESIP_CHAN;
  796. if(DEBUG)
  797. printf( "BARESIP_STATUS [%d]\n", BARESIP_STATUS );
  798. if(BARESIP_STATUS == RINGING || BARESIP_STATUS == INUSE)
  799. {
  800. strcpy(cmd,"{\"cmd\":\"hangup\",\"data\":\"\"}");
  801. if(DEBUG)
  802. printf( "hangup call\n" );
  803. control_cmd(channel, cmd);
  804. writeLog( FUN, "API Hangup", "" );
  805. }
  806. }
  807. void sipphone_loop_start()
  808. {
  809. char cmd[MAX_PIPE_BUFSIZE], hversion[16];
  810. int channel = BARESIP_CHAN;
  811. if(DEBUG)
  812. printf( "BARESIP_STATUS [%d]\n", BARESIP_STATUS );
  813. if(BARESIP_STATUS == IDLE || BARESIP_STATUS == OFFLINE)
  814. {
  815. strcpy(cmd,"{\"cmd\":\"auloop\",\"data\":\"48000 1\"}");
  816. if(DEBUG)
  817. printf( "audio loop\n" );
  818. control_cmd(channel, cmd);
  819. GetCmdValue(SPK_CONF, "system:hard_version", hversion, sizeof(hversion));
  820. if(strcmp(hversion, "Ver3.2") == 0)
  821. system("/etc/scripts/pa_mute.sh 0;echo 0 > /sys/class/gpio/gpio143/value");
  822. else
  823. system("/etc/scripts/pa_mute.sh 0;echo 0 > /sys/class/gpio/gpio134/value");
  824. BARESIP_STATUS = LOOPSTART;
  825. writeLog( FUN, "API Audio Loop", "Start" );
  826. }
  827. }
  828. void sipphone_loop_stop()
  829. {
  830. char cmd[MAX_PIPE_BUFSIZE], hversion[16];
  831. int channel = BARESIP_CHAN;
  832. if(DEBUG)
  833. printf( "BARESIP_STATUS [%d]\n", BARESIP_STATUS );
  834. if(BARESIP_STATUS == LOOPSTART)
  835. {
  836. strcpy(cmd,"{\"cmd\":\"auloop_stop\",\"data\":\"\"}");
  837. if(DEBUG)
  838. printf( "hangup call\n" );
  839. control_cmd(channel, cmd);
  840. GetCmdValue(SPK_CONF, "system:hard_version", hversion, sizeof(hversion));
  841. if(strcmp(hversion, "Ver3.2") == 0)
  842. system("/etc/scripts/pa_mute.sh 1;echo 1 > /sys/class/gpio/gpio143/value");
  843. else
  844. system("/etc/scripts/pa_mute.sh 1;echo 1 > /sys/class/gpio/gpio134/value");
  845. BARESIP_STATUS = IDLE;
  846. writeLog( FUN, "API Audio Loop", "Stop" );
  847. }
  848. }
  849. void *playTimer(void *arg)
  850. {
  851. char cmd[32];
  852. PlayInfo *p = arg;
  853. long t = p->duration*1000*1000;
  854. usleep(t);
  855. vlcInfo.state = FALSE;
  856. sprintf(cmd,"kill -9 %d",vlcInfo.pid);
  857. system(cmd);
  858. writeLog(FUN, "Specified duration expires", vlcInfo.param);
  859. }
  860. void *handle_playAudio(void *arg)
  861. {
  862. char syscmd[256];
  863. int status;
  864. PlayInfo *p = arg;
  865. if(strlen(p->url) > 7 && (strncmp(p->url, "http://", 7) == 0 || strncmp(p->url, "rtsp://", 7) == 0 || strncmp(p->url, "ftp://", 6) == 0))
  866. {
  867. if(p->volume >= 0)
  868. {
  869. sprintf(syscmd, "vlc -I dummy --network-caching=100 --gain=%.02f --play-and-exit '%s'", (float) p->volume/100, p->url);
  870. sprintf(vlcInfo.param,"URL: %s; valume: %d", p->url, p->volume);
  871. }
  872. else
  873. {
  874. sprintf(syscmd, "vlc -I dummy --network-caching=100 --gain=%.02f --play-and-exit '%s'", (float) p->volume/100, p->url);
  875. sprintf(vlcInfo.param,"URL: %s", p->url);
  876. }
  877. char *argv[] = {"sh","-c",syscmd, NULL};
  878. status = posix_spawn(&vlcInfo.pid,"/bin/sh",NULL,NULL,argv,NULL);
  879. if(status == 0)
  880. {
  881. vlcInfo.state = TRUE;
  882. amplifier_switch(TRUE);
  883. if(p->duration > 0)
  884. {
  885. pthread_t thread_audio;
  886. char strtmp[32];
  887. pthread_create(&thread_audio, NULL, playTimer, p);
  888. pthread_detach(thread_audio);
  889. sprintf(strtmp,"; duration: %ds", p->duration);
  890. strcat(vlcInfo.param, strtmp);
  891. }
  892. writeLog(FUN,"API Play URL Audio", vlcInfo.param);
  893. if(waitpid(vlcInfo.pid, &status, 0) != -1)
  894. {
  895. amplifier_switch(FALSE);
  896. printf("Child exited with status %i\n", status);
  897. if(vlcInfo.state)
  898. {
  899. writeLog(FUN, "Audio file playback ends", vlcInfo.param);
  900. vlcInfo.state = FALSE;
  901. }
  902. }
  903. }
  904. }
  905. free(p);
  906. }
  907. //gpio控制指令处理
  908. void ProcessAPIReply( redisReply * pReply )
  909. {
  910. cJSON *pJson = NULL, *subJson = NULL;
  911. redisReply * pSubReply = NULL;
  912. char cmd[MAX_PIPE_BUFSIZE], shellcmd[MAX_PIPE_BUFSIZE];
  913. char sipphone[8],relay[8],player[8],strtmp[64];
  914. int channel = BARESIP_CHAN;
  915. if ( pReply->elements == 2 )
  916. {
  917. pSubReply = pReply->element[1];
  918. if(DEBUG)
  919. printf( "Msg [%s]\n", pSubReply->str );
  920. pJson = cJSON_Parse(pSubReply->str);
  921. if ( pJson ) {
  922. if(cJSON_GetObjectItem(pJson, "type"))
  923. {
  924. if(strcmp(cJSON_GetObjectItem(pJson, "type")->valuestring, "sipphone") == 0)
  925. {
  926. GetCmdValue(SPK_CONF, "api:call_enable", sipphone, sizeof(sipphone));
  927. if(cJSON_GetObjectItem(pJson, "action")){
  928. if(strcmp(sipphone, "yes") == 0)
  929. {
  930. if(strcmp(cJSON_GetObjectItem(pJson, "action")->valuestring, "call") == 0)
  931. {
  932. if(cJSON_GetObjectItem(pJson, "data"))
  933. {
  934. subJson = cJSON_GetObjectItem(pJson, "data");
  935. sipphone_call(cJSON_GetObjectItem(subJson, "number")->valuestring, cJSON_GetObjectItem(subJson, "line")->valuestring);
  936. }
  937. }
  938. else if(strcmp(cJSON_GetObjectItem(pJson, "action")->valuestring, "answer") == 0)
  939. {
  940. sipphone_answer();
  941. }
  942. else if(strcmp(cJSON_GetObjectItem(pJson, "action")->valuestring, "hangup") == 0)
  943. {
  944. sipphone_hangup();
  945. }
  946. }
  947. if(strcmp(cJSON_GetObjectItem(pJson, "action")->valuestring, "auloopstart") == 0)
  948. {
  949. sipphone_loop_start();
  950. }
  951. else if(strcmp(cJSON_GetObjectItem(pJson, "action")->valuestring, "auloopstop") == 0)
  952. {
  953. sipphone_loop_stop();
  954. }
  955. }
  956. }
  957. else if(strcmp(cJSON_GetObjectItem(pJson, "type")->valuestring, "relay") == 0)
  958. {
  959. if(cJSON_GetObjectItem(pJson, "action"))
  960. {
  961. if(strcmp(cJSON_GetObjectItem(pJson, "action")->valuestring, "on") == 0)
  962. {
  963. outputControl(GPIO_RELAY, GPIO_ON);
  964. subJson = cJSON_GetObjectItem(pJson, "data");
  965. if(subJson){
  966. delay = cJSON_GetObjectItem(subJson, "duration")->valueint;
  967. if(delay > 0)
  968. {
  969. int ret_thrd_delay;
  970. pthread_t thread_delay;
  971. ret_thrd_delay = pthread_create(&thread_delay, NULL, gpioDelayControl, NULL);
  972. if (ret_thrd_delay != 0) {
  973. printf("create thread_delay gpioDelayControl failed\n");
  974. cJSON_Delete(pJson);
  975. return;
  976. }
  977. pthread_detach(thread_delay);
  978. }
  979. }
  980. }
  981. else if(strcmp(cJSON_GetObjectItem(pJson, "action")->valuestring, "off") == 0)
  982. {
  983. outputControl(GPIO_RELAY, GPIO_OFF);
  984. }
  985. }
  986. }
  987. else if(strcmp(cJSON_GetObjectItem(pJson, "type")->valuestring, "player") == 0)
  988. {
  989. if(cJSON_GetObjectItem(pJson, "action"))
  990. {
  991. if(strcmp(cJSON_GetObjectItem(pJson, "action")->valuestring, "start") == 0)
  992. {
  993. subJson = cJSON_GetObjectItem(pJson, "data");
  994. if(subJson && cJSON_GetObjectItem(subJson, "repeat") && cJSON_GetObjectItem(subJson, "volume"))
  995. {
  996. int repeat = cJSON_GetObjectItem(subJson, "repeat")->valueint;
  997. int volume = cJSON_GetObjectItem(subJson, "volume")->valueint;
  998. if(volume >= 0)
  999. {
  1000. sprintf(cmd,"{\"cmd\":\"setaudiotempvol\",\"data\":\"%d\"}",volume);
  1001. control_cmd(channel, cmd);
  1002. }
  1003. sprintf(cmd,"{\"cmd\":\"play\",\"data\":\"%s:%d\"}",cJSON_GetObjectItem(subJson, "file")->valuestring,repeat);
  1004. control_cmd(channel, cmd);
  1005. PLAYING = TRUE;
  1006. sprintf(strtmp, "File: %s; Repeat: %d; Volume: %d", cJSON_GetObjectItem(subJson, "file")->valuestring, repeat, volume);
  1007. writeLog( FUN, "API Play Auido", strtmp );
  1008. }
  1009. }
  1010. else if(strcmp(cJSON_GetObjectItem(pJson, "action")->valuestring, "stop") == 0)
  1011. {
  1012. sprintf(cmd,"{\"cmd\":\"play\",\"data\":\"\"}");
  1013. control_cmd(channel, cmd);
  1014. PLAYING = FALSE;
  1015. writeLog( FUN, "API Stop Auido", "" );
  1016. }
  1017. }
  1018. }
  1019. else if(strcmp(cJSON_GetObjectItem(pJson, "type")->valuestring, "urlplayer") == 0)
  1020. {
  1021. if(cJSON_GetObjectItem(pJson, "action"))
  1022. {
  1023. if(strcmp(cJSON_GetObjectItem(pJson, "action")->valuestring, "start") == 0)
  1024. {
  1025. subJson = cJSON_GetObjectItem(pJson, "data");
  1026. if(subJson && cJSON_GetObjectItem(subJson, "duration") && cJSON_GetObjectItem(subJson, "volume"))
  1027. {
  1028. pthread_t thread_audio;
  1029. int ret_thrd;
  1030. PlayInfo *playAudioInfo = malloc(sizeof(PlayInfo));
  1031. playAudioInfo->duration = cJSON_GetObjectItem(subJson, "duration")->valueint;
  1032. playAudioInfo->volume = cJSON_GetObjectItem(subJson, "volume")->valueint;
  1033. strcpy(playAudioInfo->url, cJSON_GetObjectItem(subJson, "url")->valuestring);
  1034. ret_thrd = pthread_create(&thread_audio, NULL, handle_playAudio, playAudioInfo);
  1035. if (ret_thrd != 0)
  1036. {
  1037. printf("create thread1 handle_playAudio failed\n");
  1038. free(playAudioInfo);
  1039. cJSON_Delete(pJson);
  1040. return;
  1041. }
  1042. pthread_detach(thread_audio);
  1043. }
  1044. }
  1045. else if(strcmp(cJSON_GetObjectItem(pJson, "action")->valuestring, "stop") == 0)
  1046. {
  1047. if(vlcInfo.state)
  1048. {
  1049. sprintf(cmd,"kill -9 %d",vlcInfo.pid);
  1050. system(cmd);
  1051. vlcInfo.state = FALSE;
  1052. writeLog(FUN, "Playback stops by API call", vlcInfo.param);
  1053. }
  1054. }
  1055. }
  1056. }
  1057. }
  1058. }else{
  1059. printf( "parse failed!\n");
  1060. }
  1061. if(pJson != NULL) cJSON_Delete(pJson);
  1062. }
  1063. }
  1064. /*
  1065. * 接收控制指令.
  1066. */
  1067. void *api_control()
  1068. {
  1069. redisContext * pContext = redisConnectUnix(unix_socket_path);
  1070. if ( NULL == pContext || pContext->err == 1 )
  1071. {
  1072. printf( "%s\n", pContext->errstr );
  1073. exit( -1 );
  1074. }
  1075. char * pKey = "api-channel";
  1076. redisReply * pReply;
  1077. while(1){
  1078. pReply = NULL;
  1079. pReply = redisCommand( pContext, "BRPOP %s 60", pKey );
  1080. if(pReply != NULL && pReply->type == REDIS_REPLY_ARRAY){
  1081. ProcessAPIReply( pReply );
  1082. }
  1083. if(pReply != NULL) freeReplyObject( pReply );
  1084. }
  1085. redisFree( pContext );
  1086. }
  1087. //解析音量设置数据
  1088. void ProcessVolumeReply( redisReply * pReply )
  1089. {
  1090. cJSON *pJson = NULL;
  1091. redisReply * pSubReply = NULL;
  1092. char cmd[MAX_PIPE_BUFSIZE];
  1093. int channel = BARESIP_CHAN;
  1094. if ( pReply != NULL && pReply->elements == 3 )
  1095. {
  1096. pSubReply = pReply->element[2];
  1097. pJson = cJSON_Parse(pSubReply->str);
  1098. if ( pJson ) {
  1099. if(cJSON_GetObjectItem(pJson, "sip_volume"))
  1100. {
  1101. sprintf(cmd,"{\"cmd\":\"setvol\",\"data\":\"%d\"}",cJSON_GetObjectItem(pJson, "sip_volume")->valueint);
  1102. control_cmd(channel, cmd);
  1103. }
  1104. }else{
  1105. printf( "parse failed!\n");
  1106. }
  1107. if(pJson != NULL) cJSON_Delete(pJson);
  1108. }
  1109. }
  1110. /*
  1111. * 订阅音量信息.
  1112. */
  1113. void *get_volume_info()
  1114. {
  1115. redisContext * pContext = redisConnectUnix(unix_socket_path);
  1116. if ( NULL == pContext || pContext->err == 1 )
  1117. {
  1118. printf( "%s\n", pContext->errstr );
  1119. exit( -1 );
  1120. }
  1121. char * pKey = "volume-value-channel";
  1122. redisReply * pReply = redisCommand( pContext, "SUBSCRIBE %s", pKey );
  1123. freeReplyObject( pReply );
  1124. while ( redisGetReply( pContext, (void **)&pReply ) == REDIS_OK )
  1125. {
  1126. ProcessVolumeReply( pReply );
  1127. freeReplyObject( pReply );
  1128. }
  1129. redisFree( pContext );
  1130. }
  1131. int main(int argc, char *argv[]){
  1132. char model[16];
  1133. int ret_thrd1,ret_thrd2;
  1134. pthread_t thread1, thread2;
  1135. if(argc == 2 && strcmp(argv[1], "debug") == 0)
  1136. DEBUG = TRUE;
  1137. redisClient = create_redis_client(unix_socket_path);
  1138. //启动线程订阅BARESIP实时状态
  1139. ret_thrd1 = pthread_create(&thread1, NULL, baresip_status, NULL);
  1140. if (ret_thrd1 != 0) {
  1141. printf("create thread1 baresip_status failed\n");
  1142. return 0;
  1143. }
  1144. //启动线程订阅音量设置
  1145. ret_thrd2 = pthread_create(&thread2, NULL, get_volume_info, NULL);
  1146. if (ret_thrd2 != 0) {
  1147. printf("create thread2 get_volume_info failed\n");
  1148. return 0;
  1149. }
  1150. api_control();
  1151. }