main.c 96 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686268726882689269026912692269326942695
  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. #include "log.h"
  17. #define Boolean int
  18. #define TRUE 1
  19. #define FALSE 0
  20. #define MAX_PIPE_BUFSIZE 256
  21. //KEYS
  22. #define UNKEY 0
  23. #define KEY1 1
  24. #define KEY2 2
  25. #define KEY3 3
  26. #define KEY4_3 4
  27. #define KEY4_10 5
  28. #define DKEY 6
  29. //SCHEDULE STATE
  30. #define ERROR -1
  31. #define STOP 0
  32. #define RUNNING 1
  33. #define PAUSED 2
  34. #define MAX_PRIORITY 10
  35. #define MAX_TRY 3
  36. //BARESIP_STATUS
  37. #define IDLE 0
  38. #define INUSE 1
  39. #define RING 2
  40. #define RINGING 3
  41. #define HOLD 4
  42. #define OFFLINE 5
  43. #define DIALING 6
  44. //BARESIP_REG
  45. #define REGISTER_FAIL 0
  46. #define REGISTER_OK 1
  47. //LED_STATUS
  48. #define Led_Off 0
  49. #define Led_On 1
  50. #define Led_Fast 2
  51. #define Led_Slow 3
  52. //REDIS_CHANNEL
  53. #define BARESIP_CHAN 0
  54. #define GPIO_CHAN 1
  55. //GPIO_STATUS
  56. #define GPIO_OFF 0
  57. #define GPIO_ON 1
  58. #define SPK_CONF "/etc/speaker.conf"
  59. #define VOL_CONF "/oem/etc/volctrl.conf"
  60. #define SIPLOGPATH "/userdata/system.csv"
  61. #define CDR_CSV "/userdata/cdr.csv"
  62. #define SCHEDULE_CONF "/oem/etc/schedule.conf"
  63. #define unix_socket_path "/tmp/redis.sock"
  64. //operator log type
  65. #define BTN "BUTTON"
  66. #define FUN "FUNCTION"
  67. #define STA "SIP STATE"
  68. #define SCHED "SCHEDULE"
  69. #define GPIO_130 "gpio130"
  70. #define GPIO_RELAY "gpio67"
  71. #define GPIO_LED "gpio135"
  72. #define VAR_IP "${ip}"
  73. #define VAR_MAC "${mac}"
  74. #define VAR_UA "${ua}"
  75. #define VAR_NUM "${number}"
  76. #define AUDIO_ON "{\"name\": \"SCHEDULER-AUDIO\", \"action\": \"on\"}"
  77. #define AUDIO_OFF "{\"name\": \"SCHEDULER-AUDIO\", \"action\": \"off\"}"
  78. struct date{ //声明结构体date用于表示日期
  79. int year;
  80. int month;
  81. int day;
  82. };
  83. struct VLC_INFO{
  84. pid_t pid;
  85. int prio;
  86. char param[96];
  87. };
  88. typedef struct _playInfo{
  89. int key_id;
  90. int prio;
  91. int vol;
  92. char file[64];
  93. char times_str[8];
  94. char enBeep[8];
  95. char enSrceen[8];
  96. } PlayInfo;
  97. struct CALL_LOG{
  98. char date[16];
  99. char start[16];
  100. char end[16];
  101. char acc[32];
  102. char num[32];
  103. char direct[8];
  104. char status[16];
  105. time_t answerTime;
  106. int duration;
  107. char desc[64];
  108. };
  109. typedef struct {
  110. int in_use[5];
  111. redisContext *context[5];
  112. const char *socket_path;
  113. time_t last_activity[5];
  114. pthread_mutex_t lock;
  115. } redis_client_t;
  116. static int BARESIP_STATUS = OFFLINE;
  117. static int key1LedStatus = Led_Off;
  118. static int key2LedStatus = Led_Off;
  119. static int CURRENT_KEY = UNKEY;
  120. static int DEBUG = FALSE;
  121. static int ACCOUNT1_REG = REGISTER_FAIL;
  122. static int ACCOUNT2_REG = REGISTER_FAIL;
  123. static int ACCOUNT3_REG = REGISTER_FAIL;
  124. static int ACCOUNTP2P_REG = REGISTER_FAIL;
  125. static int press_down = FALSE;
  126. static int CURRENT_CALLS = 0;
  127. static int regcount = 0;
  128. static char DTMF_STRING[32] = "\0";
  129. static int SCHEDULE[31];
  130. struct VLC_INFO vlcInfo[64];
  131. struct CALL_LOG callInfo;
  132. static redis_client_t *redisClient;
  133. redis_client_t* create_redis_pool_client(const char *socket_path) {
  134. redis_client_t *client = (redis_client_t *) malloc(sizeof(redis_client_t));
  135. client->socket_path = socket_path;
  136. pthread_mutex_init(&client->lock, NULL);
  137. for(int i = 0; i < 5; i++)
  138. {
  139. redisContext *c = redisConnectUnix(socket_path);
  140. if (c == NULL || c->err) {
  141. if (c) {
  142. printf("Connection error: %s\n", c->errstr);
  143. redisFree(c);
  144. } else {
  145. printf("Connection error: can't allocate redis context\n");
  146. }
  147. // 可以选择重试或退出
  148. continue;
  149. }
  150. client->context[i] = c;
  151. client->in_use[i] = FALSE;
  152. client->last_activity[i] = time(NULL);
  153. }
  154. return client;
  155. }
  156. const int redis_pool_get_context(redis_client_t *client) {
  157. pthread_mutex_lock(&client->lock);
  158. redisContext *context = NULL;
  159. int idx = -1;
  160. for(int i = 0;i < 5; i++)
  161. {
  162. if(!client->in_use[i])
  163. {
  164. idx = i;
  165. client->in_use[idx] = TRUE;
  166. context = client->context[idx];
  167. redisReply *reply = redisCommand(context, "PING");
  168. if (reply == NULL || context->err) {
  169. // 连接失效,尝试重连
  170. if(DEBUG)
  171. printf( "redis connect failed, retry!\n" );
  172. redisFree(context);
  173. context = redisConnectUnix(client->socket_path);
  174. client->context[idx] = context;
  175. }
  176. freeReplyObject(reply);
  177. client->last_activity[idx] = time(NULL);
  178. break;
  179. }
  180. }
  181. pthread_mutex_unlock(&client->lock);
  182. if (context == NULL) {
  183. printf("No available connections in pool\n");
  184. }
  185. return idx;
  186. }
  187. // 释放连接
  188. void redis_pool_release_connection(redis_client_t *client, const int id) {
  189. pthread_mutex_lock(&client->lock);
  190. client->in_use[id] = FALSE;
  191. pthread_mutex_unlock(&client->lock);
  192. }
  193. void redis_command_safe(const char *format, const char *value) {
  194. const int id = redis_pool_get_context(redisClient);
  195. if (id != -1) {
  196. redisReply *reply = (redisReply *) redisCommand(redisClient->context[id], format, value);
  197. if (reply) {
  198. // 处理回复
  199. freeReplyObject(reply);
  200. }
  201. redis_pool_release_connection(redisClient, id);
  202. }
  203. }
  204. int ensure_connected(redisContext *context) {
  205. if (context == NULL || context->err) {
  206. if (context) {
  207. redisFree(context);
  208. }
  209. context = redisConnectUnix(unix_socket_path);
  210. if (context == NULL || context->err) {
  211. return -1; // 连接失败
  212. }
  213. }
  214. return 0;
  215. }
  216. void reset_callInfo()
  217. {
  218. memset(&callInfo,0,sizeof(callInfo));
  219. callInfo.duration = 0;
  220. }
  221. void *write_opnlog()
  222. {
  223. char * pKey = "writelog-channel";
  224. redisReply *pReply, *pSubReply;
  225. redisContext *redisLogContext = NULL;
  226. redisLogContext = redisConnectUnix(unix_socket_path);
  227. restart:
  228. FILE *logFp = fopen(SIPLOGPATH, "a");
  229. log_add_fp(logFp, LOG_INFO);
  230. while(1)
  231. {
  232. pReply = NULL;
  233. if (ensure_connected(redisLogContext) == 0) {
  234. pReply = redisCommand( redisLogContext, "BRPOP %s 60", pKey );
  235. if(pReply != NULL && pReply->type == REDIS_REPLY_ARRAY){
  236. pSubReply = NULL;
  237. if ( pReply->elements == 2 )
  238. {
  239. pSubReply = pReply->element[1];
  240. if(DEBUG)
  241. printf( "opnLog [%s]\n", pSubReply->str );
  242. if(strcmp(pSubReply->str, "log_clean") == 0)
  243. {
  244. fclose(logFp);
  245. freeReplyObject( pReply );
  246. sleep(5);
  247. goto restart;
  248. }
  249. else
  250. log_info("%s", pSubReply->str);
  251. }
  252. }
  253. }
  254. if(pReply != NULL) freeReplyObject( pReply );
  255. usleep(200*1000);
  256. }
  257. redisFree( redisLogContext );
  258. }
  259. void writeLog(char *type,char *action, char *remark)
  260. {
  261. char logstr[256];
  262. sprintf(logstr, "%s,%s,%s", type, action, remark);
  263. redis_command_safe("LPUSH writelog-channel %s", logstr);
  264. }
  265. //发送状态指令
  266. void state_event(char *info)
  267. {
  268. redis_command_safe("PUBLISH volume-event-channel %s", info);
  269. }
  270. //发送屏幕显示指令
  271. void screen_control(char *cmd)
  272. {
  273. redis_command_safe("PUBLISH screen-channel %s", cmd);
  274. }
  275. void insert_call_log()
  276. {
  277. FILE *cdr_fp = fopen(CDR_CSV, "a");
  278. //日期,开始时间,结束时间,账号,号码,通话时长,方向,状态,描述
  279. fprintf(cdr_fp, "%s,%s,%s,%s,%s,%d,%s,%s,%s\n",
  280. callInfo.date, callInfo.start, callInfo.end, callInfo.acc, callInfo.num, callInfo.duration,
  281. callInfo.direct, callInfo.status, callInfo.desc);
  282. fclose(cdr_fp);
  283. reset_callInfo();
  284. }
  285. void setIncomingCallInfo(char *accuri, char *num)
  286. {
  287. char acc[32];
  288. time_t nSeconds;
  289. struct tm *pTM;
  290. int year, month, hour;
  291. time(&nSeconds);
  292. pTM = localtime(&nSeconds);
  293. year = pTM->tm_year + 1900;
  294. month = pTM->tm_mon + 1;
  295. memset(acc,0,sizeof(acc));
  296. strcpy(callInfo.direct,"in");
  297. sprintf(callInfo.date, "%d-%02d-%02d", year, month, pTM->tm_mday);
  298. sprintf(callInfo.start, "%02d:%02d:%02d", pTM->tm_hour, pTM->tm_min, pTM->tm_sec);
  299. //strncpy(acc, accuri, strchr(accuri,'@') - accuri);
  300. //strcpy(callInfo.acc, acc + 4);
  301. strcpy(callInfo.acc, accuri);
  302. strcpy(callInfo.num, num);
  303. strcpy(callInfo.status, "MISSED CALL");
  304. }
  305. void setOutgoingCallInfo(char *accuri, char *num)
  306. {
  307. char acc[32];
  308. time_t nSeconds;
  309. struct tm *pTM;
  310. int year, month, hour;
  311. time(&nSeconds);
  312. pTM = localtime(&nSeconds);
  313. year = pTM->tm_year + 1900;
  314. month = pTM->tm_mon + 1;
  315. memset(acc,0,sizeof(acc));
  316. strcpy(callInfo.direct,"out");
  317. sprintf(callInfo.date, "%d-%02d-%02d", year, month, pTM->tm_mday);
  318. sprintf(callInfo.start, "%02d:%02d:%02d", pTM->tm_hour, pTM->tm_min, pTM->tm_sec);
  319. //strncpy(acc, accuri, strchr(accuri,'@') - accuri);
  320. //strcpy(callInfo.acc, acc + 4);
  321. strcpy(callInfo.acc, accuri);
  322. strcpy(callInfo.num, num);
  323. strcpy(callInfo.status, "NO ANSWER");
  324. }
  325. void setAnswerCallInfo()
  326. {
  327. time_t nSeconds;
  328. time(&nSeconds);
  329. callInfo.answerTime = nSeconds;
  330. strcpy(callInfo.status, "ANSWERED");
  331. }
  332. void setClosedCallInfo(char *param)
  333. {
  334. time_t nSeconds;
  335. struct tm *pTM;
  336. time(&nSeconds);
  337. pTM = localtime(&nSeconds);
  338. sprintf(callInfo.end, "%02d:%02d:%02d", pTM->tm_hour, pTM->tm_min, pTM->tm_sec);
  339. strcpy(callInfo.desc, param);
  340. if(callInfo.answerTime)
  341. {
  342. callInfo.duration = nSeconds - callInfo.answerTime;
  343. }
  344. insert_call_log();
  345. }
  346. /*
  347. * @file 文件路径
  348. * @value 命令结果指针
  349. * @lenth 存储结果长度
  350. */
  351. int GetCmdValue(char *file, char *key, char *value, int lenth)
  352. {
  353. dictionary * ini ;
  354. ini = iniparser_load(file);
  355. if (ini==NULL) {
  356. fprintf(stderr, "cannot parse file: %s\n", file);
  357. return FALSE ;
  358. }
  359. strcpy(value, iniparser_getstring(ini, key, ""));
  360. if(DEBUG)
  361. printf("keystr: \"%s\" ; value: %s.\n", key, value);
  362. iniparser_freedict(ini);
  363. return TRUE;
  364. }
  365. char *strrpl(char *s, const char *s1, const char *s2)
  366. {
  367. char *ptr;
  368. while (ptr = strstr(s, s1)) /* 如果在s中找到s1 */
  369. {
  370. memmove(ptr + strlen(s2) , ptr + strlen(s1), strlen(ptr) - strlen(s1) + 1);
  371. memcpy(ptr, &s2[0], strlen(s2));
  372. }
  373. return s;
  374. }
  375. //控制功放的开启/关闭,TRUE/FALSE
  376. void amplifier_switch(Boolean enable){
  377. if(enable)
  378. system("echo 1 > /sys/class/gpio/gpio5/value");
  379. else
  380. system("echo 0 > /sys/class/gpio/gpio5/value");
  381. }
  382. Boolean get_ip(char * pv)
  383. {
  384. FILE * fp;
  385. char cmdbuf[128], value[32];
  386. char *tmp=NULL;
  387. sprintf(cmdbuf,"/sbin/ifconfig eth1 | grep 'inet ' | awk '{print $2}'");
  388. fp = popen(cmdbuf, "r");
  389. if (fp == NULL) {
  390. // printf("Fail to open pipe\n");
  391. return FALSE;
  392. }
  393. memset(value,0,sizeof(value));
  394. if (!feof(fp) && fgets(value,32,fp) != NULL)
  395. ;
  396. // printf("value:%s\n", value);
  397. else {
  398. printf("ip wrong\n");
  399. return FALSE;
  400. }
  401. pclose(fp);
  402. if(strlen(value) < 10)
  403. return FALSE;
  404. if(tmp = strstr(value,"\n"))
  405. {
  406. *tmp = '\0';
  407. }
  408. strcpy(pv,value);
  409. return TRUE;
  410. }
  411. Boolean get_mac(char * pv)
  412. {
  413. FILE * fp;
  414. char cmdbuf[128], value[32];
  415. char *tmp=NULL;
  416. sprintf(cmdbuf,"ifconfig eth1 | grep ether | tr -d : | awk '{print $2}'");
  417. fp = popen(cmdbuf, "r");
  418. if (fp == NULL) {
  419. return FALSE;
  420. }
  421. memset(value,0,sizeof(value));
  422. if (!feof(fp) && fgets(value,32,fp) != NULL)
  423. ;
  424. // printf("value:%s\n", value);
  425. else {
  426. printf("ip wrong\n");
  427. return FALSE;
  428. }
  429. pclose(fp);
  430. if(strlen(value) < 10)
  431. return FALSE;
  432. if(tmp = strstr(value,"\n"))
  433. {
  434. *tmp = '\0';
  435. }
  436. strcpy(pv,value);
  437. return TRUE;
  438. }
  439. int PlayIP()
  440. {
  441. //add by ssc 2019-12-26
  442. char language[32];
  443. GetCmdValue(SPK_CONF, "system:language", language, sizeof(language));
  444. char ipaddr[16],cmd_line[240];
  445. system("/usr/bin/amixer -q sset 'Master',0 29");
  446. amplifier_switch(TRUE); //开启功放
  447. if(!get_ip(ipaddr)) {
  448. if (strcmp(language, "en") == 0){
  449. system("mpg123 -r 48000 /usr/share/sounds/en/get_ip_failed.mp3");
  450. }else{
  451. system("mpg123 -r 48000 /usr/share/sounds/cn/get_ip_failed.mp3");
  452. }
  453. return 0;
  454. }
  455. if (strcmp(language, "en") == 0){
  456. strcpy(cmd_line,"cd /usr/share/sounds/en/;mpg123 -r 48000 ");
  457. }else{
  458. strcpy(cmd_line,"cd /usr/share/sounds/cn/;mpg123 -r 48000 ");
  459. }
  460. int i;
  461. for (i=0;i<strlen(ipaddr);i++){
  462. switch(ipaddr[i])
  463. {
  464. case '0':
  465. strcat(cmd_line,"digit-0.mp3 ");
  466. break;
  467. case '1':
  468. strcat(cmd_line,"digit-1.mp3 ");
  469. break;
  470. case '2':
  471. strcat(cmd_line,"digit-2.mp3 ");
  472. break;
  473. case '3':
  474. strcat(cmd_line,"digit-3.mp3 ");
  475. break;
  476. case '4':
  477. strcat(cmd_line,"digit-4.mp3 ");
  478. break;
  479. case '5':
  480. strcat(cmd_line,"digit-5.mp3 ");
  481. break;
  482. case '6':
  483. strcat(cmd_line,"digit-6.mp3 ");
  484. break;
  485. case '7':
  486. strcat(cmd_line,"digit-7.mp3 ");
  487. break;
  488. case '8':
  489. strcat(cmd_line,"digit-8.mp3 ");
  490. break;
  491. case '9':
  492. strcat(cmd_line,"digit-9.mp3 ");
  493. break;
  494. case '.':
  495. strcat(cmd_line,"dian.mp3 ");
  496. break;
  497. }
  498. }
  499. // printf("cmd-line:%s\n", cmd_line);
  500. system(cmd_line);
  501. amplifier_switch(FALSE); //关闭功放
  502. system("/etc/scripts/set_volume.sh resume");
  503. writeLog( FUN, "Play IP Address", ipaddr );
  504. return 0;
  505. }
  506. void action_url(char *url)
  507. {
  508. char cmd[320];
  509. sprintf(cmd,"curl -k --connect-timeout 5 '%s' 2>/dev/null &",url);
  510. if(DEBUG)
  511. printf( "Command: %s\n", cmd);
  512. system(cmd);
  513. }
  514. void playBeep()
  515. {
  516. char beep[8];
  517. GetCmdValue(VOL_CONF, "volume:key_beep", beep, sizeof(beep));
  518. if(strcmp(beep, "yes") == 0)
  519. {
  520. if(BARESIP_STATUS == IDLE || BARESIP_STATUS == OFFLINE)
  521. system("/usr/sbin/redis-cli PUBLISH volume-event-channel '{\"name\": \"SIP\", \"action\": \"on\"}'");
  522. system("mpg123 /home/new-speaker/target/share/sounds/beep.mp3");
  523. usleep(400*1000);
  524. if(BARESIP_STATUS == IDLE || BARESIP_STATUS == OFFLINE)
  525. system("/usr/sbin/redis-cli PUBLISH volume-event-channel '{\"name\": \"SIP\", \"action\": \"off\"}'"); //关闭功放
  526. }
  527. }
  528. //发送控制指令
  529. void control_cmd(int channel, char *cmd)
  530. {
  531. char redisCmd[256];
  532. switch (channel)
  533. {
  534. case BARESIP_CHAN:
  535. if(DEBUG)
  536. printf( "control-channel [%s]\n", cmd );
  537. redis_command_safe("LPUSH control-channel %s", cmd );
  538. break;
  539. case GPIO_CHAN:
  540. if(DEBUG)
  541. printf( "output-channel [%s]\n", cmd );
  542. redis_command_safe("LPUSH output-channel %s", cmd );
  543. break;
  544. default:
  545. redis_command_safe("LPUSH control-channel %s", cmd );
  546. break;
  547. }
  548. }
  549. void relayControl(char *id, int enable){
  550. char cmd[64];
  551. int channel = GPIO_CHAN;
  552. if(enable){
  553. char output_type[32];
  554. GetCmdValue(SPK_CONF, "relay_ctrl:type", output_type, sizeof(output_type));
  555. sprintf(cmd,"{\"id\":\"%s\",\"type\":\"%s\"}",id,output_type);
  556. control_cmd(channel,cmd);
  557. }
  558. else
  559. {
  560. sprintf(cmd,"{\"id\":\"%s\",\"type\":\"Off\"}",id);
  561. control_cmd(channel,cmd);
  562. }
  563. }
  564. void screenControl(int enable){
  565. char cmd[64], output_type[16];
  566. GetCmdValue(SPK_CONF, "screen_ctrl:type", output_type, sizeof(output_type));
  567. if(enable){
  568. sprintf(cmd,"{\"action\": \"on\", \"id\": %s}",output_type);
  569. screen_control(cmd);
  570. }
  571. else
  572. {
  573. sprintf(cmd,"{\"action\": \"off\", \"id\": %s}",output_type);
  574. screen_control(cmd);
  575. }
  576. }
  577. void ai_ctrl(Boolean en)
  578. {
  579. char hversion[16];
  580. GetCmdValue(SPK_CONF, "system:hard_version", hversion, sizeof(hversion));
  581. if(en)
  582. {
  583. char ai[8];
  584. GetCmdValue(SPK_CONF, "ai_settings:enable", ai, sizeof(ai));
  585. if(strcmp(ai, "yes") == 0)
  586. {
  587. if(strcmp(hversion, "Ver3.2") == 0)
  588. system("echo 1 > /sys/class/gpio/gpio143/value");
  589. else
  590. system("echo 1 > /sys/class/gpio/gpio134/value");
  591. }
  592. }
  593. else
  594. {
  595. if(strcmp(hversion, "Ver3.2") == 0)
  596. system("echo 0 > /sys/class/gpio/gpio143/value");
  597. else
  598. system("echo 0 > /sys/class/gpio/gpio134/value");
  599. }
  600. }
  601. //relay延时控制
  602. void *relayDelayControl()
  603. {
  604. char delay[8];
  605. GetCmdValue(SPK_CONF, "relay_ctrl:duration", delay, sizeof(delay));
  606. usleep(atoi(delay)*1000*1000);
  607. relayControl(GPIO_RELAY, GPIO_OFF);
  608. if(DEBUG)
  609. printf( "GPIO_RELAY set off\n" );
  610. }
  611. //srceen延时控制
  612. void *screenDelayControl()
  613. {
  614. char delay[8];
  615. GetCmdValue(SPK_CONF, "screen_ctrl:duration", delay, sizeof(delay));
  616. usleep(atoi(delay)*1000*1000);
  617. screenControl(FALSE);
  618. if(DEBUG)
  619. printf( "screen set off\n" );
  620. }
  621. void *key1ScreenDelayControl()
  622. {
  623. char delay[8], srceen_id[16], strtmp[64];
  624. GetCmdValue(SPK_CONF, "intercom:screen_1_duration", delay, sizeof(delay));
  625. usleep(atoi(delay)*1000*1000);
  626. GetCmdValue(SPK_CONF, "intercom:trigger_1_id", srceen_id, sizeof(srceen_id));
  627. sprintf(strtmp,"{\"action\": \"off\", \"id\": %s}",srceen_id);
  628. screen_control(strtmp);
  629. if(DEBUG)
  630. printf( "screen set off\n" );
  631. }
  632. void *key2ScreenDelayControl()
  633. {
  634. char delay[8], srceen_id[16], strtmp[64];
  635. GetCmdValue(SPK_CONF, "intercom:screen_2_duration", delay, sizeof(delay));
  636. usleep(atoi(delay)*1000*1000);
  637. GetCmdValue(SPK_CONF, "intercom:trigger_2_id", srceen_id, sizeof(srceen_id));
  638. sprintf(strtmp,"{\"action\": \"off\", \"id\": %s}",srceen_id);
  639. screen_control(strtmp);
  640. if(DEBUG)
  641. printf( "screen set off\n" );
  642. }
  643. //呼入触发
  644. void incomingTrigger()
  645. {
  646. char relay_call_state[8],relay_state_info[16],relay_mode[16];
  647. GetCmdValue(SPK_CONF, "relay_ctrl:call_state", relay_call_state, sizeof(relay_call_state));
  648. GetCmdValue(SPK_CONF, "relay_ctrl:state_info", relay_state_info, sizeof(relay_state_info));
  649. if( strcmp(relay_call_state, "yes") == 0 && ( strcmp(relay_state_info, "incoming") == 0 || strcmp(relay_state_info, "both") == 0 ) )
  650. {
  651. relayControl(GPIO_RELAY, GPIO_ON);
  652. if(DEBUG)
  653. printf( "GPIO_RELAY set on\n" );
  654. //gpio触发后判断是否为延时复位
  655. GetCmdValue(SPK_CONF, "relay_ctrl:mode", relay_mode, sizeof(relay_mode));
  656. if( strcmp(relay_mode, "delay") == 0 )
  657. {
  658. int ret_thrd_delay;
  659. pthread_t thread_delay;
  660. ret_thrd_delay = pthread_create(&thread_delay, NULL, relayDelayControl, NULL);
  661. if (ret_thrd_delay != 0) {
  662. printf("create thread_delay relayDelayControl failed\n");
  663. return;
  664. }
  665. pthread_detach(thread_delay);
  666. }
  667. }
  668. }
  669. //呼出触发
  670. void outgoingTrigger()
  671. {
  672. char relay_call_state[8],relay_state_info[16],relay_mode[16];
  673. char screen_call_state[8], screen_state_info[16], screen_mode[16];
  674. GetCmdValue(SPK_CONF, "relay_ctrl:call_state", relay_call_state, sizeof(relay_call_state));
  675. GetCmdValue(SPK_CONF, "relay_ctrl:state_info", relay_state_info, sizeof(relay_state_info));
  676. if( strcmp(relay_call_state, "yes") == 0 && ( strcmp(relay_state_info, "outgoing") == 0 || strcmp(relay_state_info, "both") == 0 ) )
  677. {
  678. relayControl(GPIO_RELAY, GPIO_ON);
  679. if(DEBUG)
  680. printf( "GPIO_RELAY set on\n" );
  681. //gpio触发后判断是否为延时复位
  682. GetCmdValue(SPK_CONF, "relay_ctrl:mode", relay_mode, sizeof(relay_mode));
  683. if( strcmp(relay_mode, "delay") == 0 )
  684. {
  685. int ret_thrd_delay;
  686. pthread_t thread_delay;
  687. ret_thrd_delay = pthread_create(&thread_delay, NULL, relayDelayControl, NULL);
  688. if (ret_thrd_delay != 0) {
  689. printf("create thread_delay relayDelayControl failed\n");
  690. return;
  691. }
  692. pthread_detach(thread_delay);
  693. }
  694. }
  695. }
  696. //应答触发
  697. void answeredTrigger()
  698. {
  699. char cmd[MAX_PIPE_BUFSIZE];
  700. char local_beep[4], local_beep_file[64], local_beep_volume[4];
  701. char remote_beep[4], remote_beep_file[64], remote_beep_volume[4];
  702. char relay_call_state[8],relay_state_info[16],relay_mode[16];
  703. char screen_call_state[8], screen_state_info[16], screen_mode[16];
  704. setAnswerCallInfo();
  705. //切换麦克风通道为通话通道
  706. ai_ctrl(FALSE);
  707. //判断RELAY是否需要应答复位
  708. GetCmdValue(SPK_CONF, "relay_ctrl:mode", relay_mode, sizeof(relay_mode));
  709. if( strcmp(relay_mode, "answered") == 0 )
  710. {
  711. relayControl(GPIO_RELAY, GPIO_OFF);
  712. if(DEBUG)
  713. printf( "GPIO_RELAY set off\n" );
  714. }
  715. else
  716. {
  717. GetCmdValue(SPK_CONF, "relay_ctrl:call_state", relay_call_state, sizeof(relay_call_state));
  718. GetCmdValue(SPK_CONF, "relay_ctrl:state_info", relay_state_info, sizeof(relay_state_info));
  719. if( strcmp(relay_call_state, "yes") == 0 && strcmp(relay_state_info, "answered") == 0 )
  720. {
  721. relayControl(GPIO_RELAY, GPIO_ON);
  722. if(DEBUG)
  723. printf( "GPIO_RELAY set on\n" );
  724. //gpio触发后判断是否为延时复位
  725. if( strcmp(relay_mode, "delay") == 0 )
  726. {
  727. int ret_thrd_delay;
  728. pthread_t thread_delay;
  729. ret_thrd_delay = pthread_create(&thread_delay, NULL, relayDelayControl, NULL);
  730. if (ret_thrd_delay != 0) {
  731. printf("create thread_delay relayDelayControl failed\n");
  732. return;
  733. }
  734. pthread_detach(thread_delay);
  735. }
  736. }
  737. }
  738. //触发应答提示音播放
  739. GetCmdValue(SPK_CONF, "sip_function:answer_local_beep", local_beep, sizeof(local_beep));
  740. if(strcmp(local_beep, "yes") == 0)
  741. {
  742. GetCmdValue(SPK_CONF, "sip_function:answer_local_beep_file", local_beep_file, sizeof(local_beep_file));
  743. GetCmdValue(SPK_CONF, "sip_function:answer_local_beep_volume", local_beep_volume, sizeof(local_beep_volume));
  744. sprintf(cmd,"{\"cmd\":\"mixausrc_dec_start\",\"data\":\"aufile /usr/share/baresip/%s 10 %s\"}", local_beep_file, local_beep_volume);
  745. control_cmd(BARESIP_CHAN, cmd);
  746. }
  747. GetCmdValue(SPK_CONF, "sip_function:answer_remote_beep", remote_beep, sizeof(remote_beep));
  748. if(strcmp(remote_beep, "yes") == 0)
  749. {
  750. GetCmdValue(SPK_CONF, "sip_function:answer_remote_beep_file", remote_beep_file, sizeof(remote_beep_file));
  751. GetCmdValue(SPK_CONF, "sip_function:answer_remote_beep_volume", remote_beep_volume, sizeof(remote_beep_volume));
  752. sprintf(cmd,"{\"cmd\":\"mixausrc_enc_start\",\"data\":\"aufile /usr/share/baresip/%s 10 %s\"}", remote_beep_file, remote_beep_volume);
  753. control_cmd(BARESIP_CHAN, cmd);
  754. }
  755. }
  756. //挂断触发
  757. void hangupTrigger(char *param)
  758. {
  759. char cmd[MAX_PIPE_BUFSIZE];
  760. char relay_call_state[8],relay_state_info[16],relay_mode[16];
  761. char call_state[8],state_info[16],output_mode[16], beep[4], beep_file[64], beep_volume[4];
  762. char screen_call_state[8], screen_state_info[16], screen_mode[16];
  763. //触发挂断提示音播放
  764. GetCmdValue(SPK_CONF, "sip_function:hangup_beep", beep, sizeof(beep));
  765. if(strcmp(beep, "yes") == 0)
  766. {
  767. GetCmdValue(SPK_CONF, "sip_function:hangup_beep_file", beep_file, sizeof(beep_file));
  768. GetCmdValue(SPK_CONF, "sip_function:hangup_beep_volume", beep_volume, sizeof(beep_volume));
  769. sprintf(cmd,"{\"cmd\":\"setaudiotempvol\",\"data\":\"%s\"}",beep_volume);
  770. control_cmd(BARESIP_CHAN, cmd);
  771. sprintf(cmd,"{\"cmd\":\"play\",\"data\":\"%s:0\"}", beep_file);
  772. control_cmd(BARESIP_CHAN, cmd);
  773. }
  774. setClosedCallInfo(param);
  775. //判断RELAY是否需要挂断复位
  776. GetCmdValue(SPK_CONF, "relay_ctrl:mode", relay_mode, sizeof(relay_mode));
  777. if( strcmp(relay_mode, "hangup") == 0 )
  778. {
  779. relayControl(GPIO_RELAY, GPIO_OFF);
  780. if(DEBUG)
  781. printf( "GPIO_RELAY set off\n" );
  782. }
  783. else
  784. {
  785. //否则判断是否需要执行挂断触发
  786. GetCmdValue(SPK_CONF, "relay_ctrl:call_state", relay_call_state, sizeof(relay_call_state));
  787. GetCmdValue(SPK_CONF, "relay_ctrl:state_info", relay_state_info, sizeof(relay_state_info));
  788. if( strcmp(relay_call_state, "yes") == 0){
  789. if(strcmp(relay_state_info, "hangup") == 0 )
  790. {
  791. relayControl(GPIO_RELAY, GPIO_ON);
  792. if(DEBUG)
  793. printf( "GPIO_RELAY set on\n" );
  794. //gpio触发后延时复位
  795. int ret_thrd_delay;
  796. pthread_t thread_delay;
  797. ret_thrd_delay = pthread_create(&thread_delay, NULL, relayDelayControl, NULL);
  798. if (ret_thrd_delay != 0) {
  799. printf("create thread_delay relayDelayControl failed\n");
  800. return;
  801. }
  802. pthread_detach(thread_delay);
  803. }
  804. else
  805. {
  806. relayControl(GPIO_RELAY, GPIO_OFF);
  807. if(DEBUG)
  808. printf( "GPIO_RELAY set off\n" );
  809. }
  810. }
  811. }
  812. }
  813. //DTMF检测
  814. void dtmfDetect(char *dtmf)
  815. {
  816. char dtmf_event[8],dtmf_code[32],relay_mode[16];
  817. char srceen_dtmf_event[8],srceen_dtmf_code[32],srceen_mode[16];
  818. char dtmf_tmp[32] = "\0";
  819. int dtmflen,codelen,srceen_codelen, reset = FALSE;
  820. GetCmdValue(SPK_CONF, "relay_ctrl:dtmf", dtmf_event, sizeof(dtmf_event));
  821. GetCmdValue(SPK_CONF, "screen_ctrl:dtmf", srceen_dtmf_event, sizeof(srceen_dtmf_event));
  822. if( strcmp(dtmf_event, "yes") == 0 || strcmp(srceen_dtmf_event, "yes") == 0 )
  823. {
  824. strcat(DTMF_STRING,dtmf);
  825. if(DEBUG)
  826. printf( "DTMF is [%s]\n", DTMF_STRING );
  827. dtmflen = strlen(DTMF_STRING);
  828. if(strcmp(dtmf_event, "yes") == 0 )
  829. {
  830. GetCmdValue(SPK_CONF, "relay_ctrl:dtmf_code", dtmf_code, sizeof(dtmf_code));
  831. codelen = strlen(dtmf_code);
  832. if( dtmflen >= codelen )
  833. {
  834. strcpy(dtmf_tmp, DTMF_STRING + dtmflen - codelen);
  835. if( strcmp(dtmf_tmp, dtmf_code) == 0 ){
  836. relayControl(GPIO_RELAY, GPIO_ON);
  837. if(DEBUG)
  838. printf( "GPIO_RELAY set on\n" );
  839. //gpio触发后判断是否为延时复位
  840. GetCmdValue(SPK_CONF, "relay_ctrl:mode", relay_mode, sizeof(relay_mode));
  841. if( strcmp(relay_mode, "delay") == 0 )
  842. {
  843. int ret_thrd_delay;
  844. pthread_t thread_delay;
  845. ret_thrd_delay = pthread_create(&thread_delay, NULL, relayDelayControl, NULL);
  846. if (ret_thrd_delay != 0) {
  847. printf("create thread_delay relayDelayControl failed\n");
  848. return;
  849. }
  850. pthread_detach(thread_delay);
  851. }
  852. reset = TRUE;
  853. }
  854. }
  855. }
  856. if(strcmp(srceen_dtmf_event, "yes") == 0 )
  857. {
  858. GetCmdValue(SPK_CONF, "screen_ctrl:dtmf_code", srceen_dtmf_code, sizeof(srceen_dtmf_code));
  859. srceen_codelen = strlen(srceen_dtmf_code);
  860. if( dtmflen >= srceen_codelen )
  861. {
  862. strcpy(dtmf_tmp, DTMF_STRING + dtmflen - srceen_codelen);
  863. if( strcmp(dtmf_tmp, srceen_dtmf_code) == 0 ){
  864. screenControl(TRUE);
  865. if(DEBUG)
  866. printf( "screen set on\n" );
  867. //触发后判断是否为延时复位
  868. GetCmdValue(SPK_CONF, "screen_ctrl:mode", srceen_mode, sizeof(srceen_mode));
  869. if( strcmp(srceen_mode, "delay") == 0 )
  870. {
  871. int ret_thrd_delay;
  872. pthread_t thread_delay;
  873. ret_thrd_delay = pthread_create(&thread_delay, NULL, screenDelayControl, NULL);
  874. if (ret_thrd_delay != 0) {
  875. printf("create thread_delay screenDelayControl failed\n");
  876. return;
  877. }
  878. pthread_detach(thread_delay);
  879. }
  880. reset = TRUE;
  881. }
  882. }
  883. }
  884. if(reset) memset(DTMF_STRING, 0, sizeof(DTMF_STRING));
  885. }
  886. }
  887. //baresip状态监控
  888. void ProcessReply( redisReply * pReply )
  889. {
  890. cJSON *pJson;
  891. redisReply * pSubReply = NULL;
  892. char callerid[128],strtmp[256];
  893. if ( pReply != NULL && pReply->elements == 3 )
  894. {
  895. pSubReply = pReply->element[2];
  896. if(DEBUG)
  897. printf( "Msg [%s]\n", pSubReply->str );
  898. pJson = cJSON_Parse(pSubReply->str);
  899. if ( pJson ) {
  900. if(strcmp(cJSON_GetObjectItem(pJson, "direction")->valuestring, "incoming") == 0 &&
  901. strcmp(cJSON_GetObjectItem(pJson, "type")->valuestring, "CALL_ESTABLISHED") == 0)
  902. {
  903. //通话
  904. writeLog( STA, "CALL ESTABLISHED", "incoming" );
  905. //amplifier_switch(TRUE);
  906. BARESIP_STATUS = INUSE;
  907. switch(CURRENT_KEY){
  908. case KEY1:
  909. key1LedStatus = Led_Slow;
  910. key2LedStatus = Led_On;
  911. break;
  912. case KEY2:
  913. key1LedStatus = Led_On;
  914. key2LedStatus = Led_Slow;
  915. break;
  916. case UNKEY:
  917. case DKEY:
  918. key1LedStatus = Led_Slow;
  919. key2LedStatus = Led_Slow;
  920. break;
  921. }
  922. answeredTrigger();
  923. }
  924. else if(strcmp(cJSON_GetObjectItem(pJson, "direction")->valuestring, "outgoing") == 0 &&
  925. strcmp(cJSON_GetObjectItem(pJson, "type")->valuestring, "CALL_ESTABLISHED") == 0)
  926. {
  927. //通话
  928. writeLog( STA, "CALL ESTABLISHED", "outgoing" );
  929. //amplifier_switch(TRUE);
  930. BARESIP_STATUS = INUSE;
  931. switch(CURRENT_KEY){
  932. case KEY1:
  933. key1LedStatus = Led_Slow;
  934. key2LedStatus = Led_On;
  935. break;
  936. case KEY2:
  937. key1LedStatus = Led_On;
  938. key2LedStatus = Led_Slow;
  939. break;
  940. case UNKEY:
  941. case DKEY:
  942. key1LedStatus = Led_Slow;
  943. key2LedStatus = Led_Slow;
  944. break;
  945. }
  946. answeredTrigger();
  947. }
  948. else if(strcmp(cJSON_GetObjectItem(pJson, "direction")->valuestring, "incoming") == 0 &&
  949. strcmp(cJSON_GetObjectItem(pJson, "type")->valuestring, "CALL_CLOSED") == 0)
  950. {
  951. //挂断
  952. hangupTrigger(cJSON_GetObjectItem(pJson, "param")->valuestring);
  953. writeLog( STA, "CALL CLOSED", cJSON_GetObjectItem(pJson, "param")->valuestring );
  954. if(BARESIP_STATUS != OFFLINE){
  955. BARESIP_STATUS = IDLE;
  956. switch(CURRENT_KEY){
  957. case KEY1:
  958. key1LedStatus = Led_On;
  959. break;
  960. case KEY2:
  961. key2LedStatus = Led_On;
  962. break;
  963. case UNKEY:
  964. key1LedStatus = Led_On;
  965. key2LedStatus = Led_On;
  966. break;
  967. }
  968. }
  969. if(strlen(DTMF_STRING))
  970. memset(DTMF_STRING, 0, sizeof(DTMF_STRING));
  971. CURRENT_CALLS --;
  972. if(CURRENT_CALLS < 1)
  973. {
  974. //amplifier_switch(FALSE);
  975. CURRENT_CALLS = 0;
  976. ai_ctrl(TRUE);
  977. }
  978. else
  979. {
  980. control_cmd(BARESIP_CHAN, "{\"cmd\":\"resume\",\"data\":\"\"}");
  981. }
  982. }
  983. else if(strcmp(cJSON_GetObjectItem(pJson, "direction")->valuestring, "outgoing") == 0 &&
  984. strcmp(cJSON_GetObjectItem(pJson, "type")->valuestring, "CALL_CLOSED") == 0)
  985. {
  986. //挂断
  987. hangupTrigger(cJSON_GetObjectItem(pJson, "param")->valuestring);
  988. writeLog( STA, "CALL CLOSED", cJSON_GetObjectItem(pJson, "param")->valuestring );
  989. if(BARESIP_STATUS != OFFLINE){
  990. BARESIP_STATUS = IDLE;
  991. switch(CURRENT_KEY){
  992. case KEY1:
  993. key1LedStatus = Led_On;
  994. break;
  995. case KEY2:
  996. key2LedStatus = Led_On;
  997. break;
  998. case DKEY:
  999. key1LedStatus = Led_On;
  1000. key2LedStatus = Led_On;
  1001. break;
  1002. }
  1003. }
  1004. CURRENT_KEY = UNKEY;
  1005. if(strlen(DTMF_STRING))
  1006. memset(DTMF_STRING, 0, sizeof(DTMF_STRING));
  1007. CURRENT_CALLS --;
  1008. if(CURRENT_CALLS < 1)
  1009. {
  1010. CURRENT_CALLS = 0;
  1011. ai_ctrl(TRUE);
  1012. }
  1013. else
  1014. {
  1015. control_cmd(BARESIP_CHAN, "{\"cmd\":\"resume\",\"data\":\"\"}");
  1016. }
  1017. }
  1018. else if(strcmp(cJSON_GetObjectItem(pJson, "direction")->valuestring, "incoming") == 0 &&
  1019. strcmp(cJSON_GetObjectItem(pJson, "type")->valuestring, "CALL_INCOMING") == 0)
  1020. {
  1021. //呼入振铃状态
  1022. writeLog( STA, "INCOMING CALL", cJSON_GetObjectItem(pJson, "peeruri")->valuestring );
  1023. CURRENT_CALLS ++;
  1024. //amplifier_switch(TRUE);
  1025. if(BARESIP_STATUS == IDLE)
  1026. {
  1027. BARESIP_STATUS = RING;
  1028. key1LedStatus = Led_Fast;
  1029. key2LedStatus = Led_Fast;
  1030. CURRENT_KEY = UNKEY;
  1031. incomingTrigger();
  1032. }
  1033. memset(callerid, 0, sizeof(callerid));
  1034. if(strchr(cJSON_GetObjectItem(pJson, "peeruri")->valuestring,'@'))
  1035. strncpy(callerid, cJSON_GetObjectItem(pJson, "peeruri")->valuestring,
  1036. strchr(cJSON_GetObjectItem(pJson, "peeruri")->valuestring,'@') - cJSON_GetObjectItem(pJson, "peeruri")->valuestring);
  1037. else
  1038. strcpy(callerid, cJSON_GetObjectItem(pJson, "peeruri")->valuestring);
  1039. setIncomingCallInfo(cJSON_GetObjectItem(pJson, "accountaor")->valuestring, callerid + 4);
  1040. }
  1041. else if(strcmp(cJSON_GetObjectItem(pJson, "direction")->valuestring, "outgoing") == 0 &&
  1042. strcmp(cJSON_GetObjectItem(pJson, "type")->valuestring, "CALL_OUTGOING") == 0)
  1043. {
  1044. //呼出回铃状态
  1045. writeLog( STA, "OUTGOING CALL", cJSON_GetObjectItem(pJson, "peeruri")->valuestring );
  1046. CURRENT_CALLS ++;
  1047. //amplifier_switch(TRUE);
  1048. if(BARESIP_STATUS == IDLE || BARESIP_STATUS == DIALING)
  1049. {
  1050. BARESIP_STATUS = RINGING;
  1051. switch(CURRENT_KEY){
  1052. case KEY1:
  1053. key1LedStatus = Led_Fast;
  1054. break;
  1055. case KEY2:
  1056. key2LedStatus = Led_Fast;
  1057. break;
  1058. }
  1059. outgoingTrigger();
  1060. }
  1061. memset(callerid, 0, sizeof(callerid));
  1062. if(strchr(cJSON_GetObjectItem(pJson, "peeruri")->valuestring,'@'))
  1063. strncpy(callerid, cJSON_GetObjectItem(pJson, "peeruri")->valuestring,
  1064. strchr(cJSON_GetObjectItem(pJson, "peeruri")->valuestring,'@') - cJSON_GetObjectItem(pJson, "peeruri")->valuestring);
  1065. else
  1066. strncpy(callerid, cJSON_GetObjectItem(pJson, "peeruri")->valuestring,
  1067. strchr(cJSON_GetObjectItem(pJson, "peeruri")->valuestring,';') - cJSON_GetObjectItem(pJson, "peeruri")->valuestring);
  1068. setOutgoingCallInfo(cJSON_GetObjectItem(pJson, "accountaor")->valuestring, callerid + 4);
  1069. }
  1070. else if(strcmp(cJSON_GetObjectItem(pJson, "type")->valuestring, "CALL_DTMF_START") == 0)
  1071. {
  1072. //接收DTMF
  1073. writeLog( FUN, "RECEIVE DTMF", cJSON_GetObjectItem(pJson, "param")->valuestring );
  1074. dtmfDetect(cJSON_GetObjectItem(pJson, "param")->valuestring);
  1075. }
  1076. else if(strcmp(cJSON_GetObjectItem(pJson, "type")->valuestring, "REGISTER_OK") == 0)
  1077. {
  1078. //如果是注册成功点亮指示灯
  1079. char enac1[8],enac2[8],enac3[8],accountaor1[192], accountaor2[192], accountaor3[192];
  1080. char account1[32], domain1[128], account2[32], domain2[128], account3[32], domain3[128];
  1081. if(BARESIP_STATUS == OFFLINE || BARESIP_STATUS == DIALING || strcmp(cJSON_GetObjectItem(pJson, "class")->valuestring, "init register") == 0)
  1082. {
  1083. BARESIP_STATUS = IDLE;
  1084. key1LedStatus = Led_On;
  1085. key2LedStatus = Led_On;
  1086. CURRENT_CALLS = 0;
  1087. }
  1088. if(cJSON_GetObjectItem(pJson, "accountaor") != NULL)
  1089. {
  1090. GetCmdValue(SPK_CONF, "account_info_1:enable", enac1, sizeof(enac1));
  1091. if(strcmp(enac1, "yes") == 0 && ACCOUNT1_REG == REGISTER_FAIL)
  1092. {
  1093. GetCmdValue(SPK_CONF, "account_info_1:username", account1, sizeof(account1));
  1094. GetCmdValue(SPK_CONF, "account_info_1:domain", domain1, sizeof(domain1));
  1095. if(strlen(domain1) == 0)
  1096. {
  1097. GetCmdValue(SPK_CONF, "account_info_1:server", domain1, sizeof(domain1));
  1098. }
  1099. memset(accountaor1, '\0', sizeof(accountaor1));
  1100. sprintf(accountaor1, "sip:%s@%s", account1, domain1);
  1101. if (strcmp(cJSON_GetObjectItem(pJson, "accountaor")->valuestring, accountaor1) == 0)
  1102. {
  1103. ACCOUNT1_REG = REGISTER_OK;
  1104. cJSON_Delete(pJson);
  1105. sprintf(strtmp,"Primary SIP Account <%s>",accountaor1);
  1106. writeLog( STA, "SIP REGISTERED", strtmp );
  1107. return;
  1108. }
  1109. }
  1110. GetCmdValue(SPK_CONF, "account_info_2:enable", enac2, sizeof(enac2));
  1111. if(strcmp(enac2, "yes") == 0 && ACCOUNT2_REG == REGISTER_FAIL)
  1112. {
  1113. GetCmdValue(SPK_CONF, "account_info_2:username", account2, sizeof(account2));
  1114. GetCmdValue(SPK_CONF, "account_info_2:domain", domain2, sizeof(domain2));
  1115. if(strlen(domain2) == 0)
  1116. {
  1117. GetCmdValue(SPK_CONF, "account_info_2:server", domain2, sizeof(domain2));
  1118. }
  1119. memset(accountaor2, '\0', sizeof(accountaor2));
  1120. sprintf(accountaor2, "sip:%s@%s", account2, domain2);
  1121. if (strcmp(cJSON_GetObjectItem(pJson, "accountaor")->valuestring, accountaor2) == 0)
  1122. {
  1123. ACCOUNT2_REG = REGISTER_OK;
  1124. cJSON_Delete(pJson);
  1125. sprintf(strtmp,"Secondary SIP Account-1 <%s>",accountaor2);
  1126. writeLog( STA, "SIP REGISTERED", strtmp );
  1127. return;
  1128. }
  1129. }
  1130. GetCmdValue(SPK_CONF, "account_info_3:enable", enac3, sizeof(enac3));
  1131. if(strcmp(enac3, "yes") == 0 && ACCOUNT3_REG == REGISTER_FAIL)
  1132. {
  1133. GetCmdValue(SPK_CONF, "account_info_3:username", account3, sizeof(account3));
  1134. GetCmdValue(SPK_CONF, "account_info_3:domain", domain3, sizeof(domain3));
  1135. if(strlen(domain3) == 0)
  1136. {
  1137. GetCmdValue(SPK_CONF, "account_info_3:server", domain3, sizeof(domain3));
  1138. }
  1139. memset(accountaor3, '\0', sizeof(accountaor3));
  1140. sprintf(accountaor3, "sip:%s@%s", account3, domain3);
  1141. if (strcmp(cJSON_GetObjectItem(pJson, "accountaor")->valuestring, accountaor3) == 0)
  1142. {
  1143. ACCOUNT3_REG = REGISTER_OK;
  1144. cJSON_Delete(pJson);
  1145. sprintf(strtmp,"Secondary SIP Account-2 <%s>",accountaor3);
  1146. writeLog( STA, "SIP REGISTERED", strtmp );
  1147. return;
  1148. }
  1149. }
  1150. }
  1151. regcount ++;
  1152. }
  1153. else if(strcmp(cJSON_GetObjectItem(pJson, "type")->valuestring, "REGISTER_FAIL") == 0 )
  1154. {
  1155. char enac1[8],enac2[8],enac3[8],accountaor1[192], accountaor2[192], accountaor3[192];
  1156. char account1[32], domain1[128], account2[32], domain2[128], account3[32], domain3[128];
  1157. if(cJSON_GetObjectItem(pJson, "accountaor") != NULL)
  1158. {
  1159. GetCmdValue(SPK_CONF, "account_info_1:enable", enac1, sizeof(enac1));
  1160. if(strcmp(enac1, "yes") == 0 && ACCOUNT1_REG == REGISTER_OK)
  1161. {
  1162. GetCmdValue(SPK_CONF, "account_info_1:username", account1, sizeof(account1));
  1163. GetCmdValue(SPK_CONF, "account_info_1:domain", domain1, sizeof(domain1));
  1164. if(strlen(domain1) == 0)
  1165. {
  1166. GetCmdValue(SPK_CONF, "account_info_1:server", domain1, sizeof(domain1));
  1167. }
  1168. memset(accountaor1, '\0', sizeof(accountaor1));
  1169. sprintf(accountaor1, "sip:%s@%s", account1, domain1);
  1170. if (strcmp(cJSON_GetObjectItem(pJson, "accountaor")->valuestring, accountaor1) == 0)
  1171. {
  1172. ACCOUNT1_REG = REGISTER_FAIL;
  1173. if( ACCOUNT2_REG == REGISTER_FAIL && ACCOUNT3_REG == REGISTER_FAIL && ACCOUNTP2P_REG == REGISTER_FAIL ){
  1174. BARESIP_STATUS = OFFLINE;
  1175. key1LedStatus = Led_Off;
  1176. key2LedStatus = Led_Off;
  1177. }
  1178. sprintf(strtmp,"Primary Account REGISTER FAILED <%s>",accountaor1);
  1179. writeLog( STA, strtmp, cJSON_GetObjectItem(pJson, "param")->valuestring );
  1180. cJSON_Delete(pJson);
  1181. return;
  1182. }
  1183. }
  1184. GetCmdValue(SPK_CONF, "account_info_2:enable", enac2, sizeof(enac2));
  1185. if(strcmp(enac2, "yes") == 0 && ACCOUNT2_REG == REGISTER_OK)
  1186. {
  1187. GetCmdValue(SPK_CONF, "account_info_2:username", account2, sizeof(account2));
  1188. GetCmdValue(SPK_CONF, "account_info_2:domain", domain2, sizeof(domain2));
  1189. if(strlen(domain2) == 0)
  1190. {
  1191. GetCmdValue(SPK_CONF, "account_info_2:server", domain2, sizeof(domain2));
  1192. }
  1193. memset(accountaor2, '\0', sizeof(accountaor2));
  1194. sprintf(accountaor2, "sip:%s@%s", account2, domain2);
  1195. if (strcmp(cJSON_GetObjectItem(pJson, "accountaor")->valuestring, accountaor2) == 0)
  1196. {
  1197. ACCOUNT2_REG = REGISTER_FAIL;
  1198. if( ACCOUNT1_REG == REGISTER_FAIL && ACCOUNT3_REG == REGISTER_FAIL && ACCOUNTP2P_REG == REGISTER_FAIL ){
  1199. BARESIP_STATUS = OFFLINE;
  1200. key1LedStatus = Led_Off;
  1201. key2LedStatus = Led_Off;
  1202. }
  1203. sprintf(strtmp,"Secondary Account-1 REGISTER FAILED <%s>",accountaor2);
  1204. writeLog( STA, strtmp, cJSON_GetObjectItem(pJson, "param")->valuestring );
  1205. cJSON_Delete(pJson);
  1206. return;
  1207. }
  1208. }
  1209. GetCmdValue(SPK_CONF, "account_info_3:enable", enac3, sizeof(enac3));
  1210. if(strcmp(enac3, "yes") == 0 && ACCOUNT3_REG == REGISTER_OK)
  1211. {
  1212. GetCmdValue(SPK_CONF, "account_info_3:username", account3, sizeof(account3));
  1213. GetCmdValue(SPK_CONF, "account_info_3:domain", domain3, sizeof(domain3));
  1214. if(strlen(domain3) == 0)
  1215. {
  1216. GetCmdValue(SPK_CONF, "account_info_3:server", domain3, sizeof(domain3));
  1217. }
  1218. memset(accountaor3, '\0', sizeof(accountaor3));
  1219. sprintf(accountaor3, "sip:%s@%s", account3, domain3);
  1220. if (strcmp(cJSON_GetObjectItem(pJson, "accountaor")->valuestring, accountaor3) == 0)
  1221. {
  1222. ACCOUNT3_REG = REGISTER_FAIL;
  1223. if( ACCOUNT1_REG == REGISTER_FAIL && ACCOUNT2_REG == REGISTER_FAIL && ACCOUNTP2P_REG == REGISTER_FAIL ){
  1224. BARESIP_STATUS = OFFLINE;
  1225. key1LedStatus = Led_Off;
  1226. key2LedStatus = Led_Off;
  1227. }
  1228. sprintf(strtmp,"Secondary Account-2 REGISTER FAILED <%s>",accountaor3);
  1229. writeLog( STA, strtmp, cJSON_GetObjectItem(pJson, "param")->valuestring );
  1230. cJSON_Delete(pJson);
  1231. return;
  1232. }
  1233. }
  1234. }
  1235. regcount ++;
  1236. }
  1237. else if(strcmp(cJSON_GetObjectItem(pJson, "type")->valuestring, "EXIT") == 0)
  1238. {
  1239. //如果是注册失败熄灭指示灯
  1240. BARESIP_STATUS = OFFLINE;
  1241. key1LedStatus = Led_Off;
  1242. key2LedStatus = Led_Off;
  1243. ACCOUNT1_REG = REGISTER_FAIL;
  1244. ACCOUNT2_REG = REGISTER_FAIL;
  1245. ACCOUNT3_REG = REGISTER_FAIL;
  1246. writeLog( STA, "APP EXIT", "" );
  1247. CURRENT_CALLS = 0;
  1248. }
  1249. else if(cJSON_GetObjectItem(pJson, "event")->type == 1 && cJSON_GetObjectItem(pJson, "event")->valueint == 0){
  1250. if(strncmp(cJSON_GetObjectItem(pJson, "data")->valuestring,"\n--- User Agents",16) == 0)
  1251. {
  1252. char p2penable[8];
  1253. GetCmdValue(SPK_CONF, "account_info_p2p:enable", p2penable, sizeof(p2penable));
  1254. if(strcmp(p2penable,"yes") == 0)
  1255. {
  1256. BARESIP_STATUS = IDLE;
  1257. key1LedStatus = Led_On;
  1258. key2LedStatus = Led_On;
  1259. if(ACCOUNTP2P_REG == REGISTER_FAIL)
  1260. {
  1261. ACCOUNTP2P_REG = REGISTER_OK;
  1262. writeLog( STA, "P2P ACCOUNT", "Enabled" );
  1263. }
  1264. }
  1265. else if(ACCOUNTP2P_REG == REGISTER_OK)
  1266. {
  1267. ACCOUNTP2P_REG = REGISTER_FAIL;
  1268. writeLog( STA, "P2P ACCOUNT", "Disabled" );
  1269. }
  1270. }
  1271. }
  1272. if(DEBUG)
  1273. printf( "Baresip Status is: %d\n", BARESIP_STATUS );
  1274. }else{
  1275. printf( "parse failed!\n");
  1276. }
  1277. if(pJson != NULL) cJSON_Delete(pJson);
  1278. }
  1279. }
  1280. /*
  1281. * 订阅baresip实时状态.
  1282. */
  1283. void *baresip_status()
  1284. {
  1285. redisContext * pContext = redisConnectUnix(unix_socket_path);
  1286. if ( NULL == pContext || pContext->err == 1 )
  1287. {
  1288. printf( "%s\n", pContext->errstr );
  1289. exit( -1 );
  1290. }
  1291. char * pKey = "session-channel";
  1292. redisReply * pReply = redisCommand( pContext, "SUBSCRIBE %s", pKey );
  1293. freeReplyObject( pReply );
  1294. while ( redisGetReply( pContext, (void **)&pReply ) == REDIS_OK )
  1295. {
  1296. ProcessReply( pReply );
  1297. freeReplyObject( pReply );
  1298. }
  1299. redisFree( pContext );
  1300. }
  1301. int get_line(int * line_id)
  1302. {
  1303. char enac[8], strtmp[32];
  1304. int id = 0;
  1305. memset(line_id,-1,sizeof(line_id));
  1306. for(int i = 1; i < 4;i ++)
  1307. {
  1308. bzero(strtmp, sizeof(strtmp));
  1309. sprintf(strtmp,"account_info_%d:enable",i);
  1310. GetCmdValue(SPK_CONF, strtmp, enac, sizeof(enac));
  1311. if(strcmp(enac,"yes") == 0)
  1312. {
  1313. line_id[i] = id;
  1314. id ++;
  1315. }
  1316. }
  1317. return TRUE;
  1318. }
  1319. //按键动作
  1320. void keyAction(int key)
  1321. {
  1322. char cmd[MAX_PIPE_BUFSIZE];
  1323. char accountaor[192],strtmp[64];
  1324. char account[32], enable[8],url[256],ipaddr[16],macaddr[16];
  1325. char onekey_num[32],onekey_line[24],repress_cancel[8];
  1326. int channel = BARESIP_CHAN, line_id[4];
  1327. if(DEBUG)
  1328. printf( "BARESIP_STATUS [%d]\n", BARESIP_STATUS );
  1329. switch(key){
  1330. case KEY1://处理按键1动作
  1331. if( CURRENT_KEY == UNKEY || CURRENT_KEY == KEY1 )
  1332. {
  1333. switch(BARESIP_STATUS)
  1334. {
  1335. case IDLE:
  1336. CURRENT_KEY = KEY1;
  1337. BARESIP_STATUS = DIALING;
  1338. GetCmdValue(SPK_CONF, "intercom:onekey_1_num", onekey_num, sizeof(onekey_num));
  1339. GetCmdValue(SPK_CONF, "intercom:onekey_1_line", onekey_line, sizeof(onekey_line));
  1340. if(strlen(onekey_num) == 0)
  1341. {
  1342. BARESIP_STATUS = IDLE;
  1343. break;
  1344. }
  1345. get_line(line_id);
  1346. if(strcmp(onekey_line,"auto") == 0)
  1347. {
  1348. if(DEBUG)
  1349. printf("ACCOUNT1 is %d, ACCOUNT2 is %d, ACCOUNT3 is %d\n",ACCOUNT1_REG,ACCOUNT2_REG,ACCOUNT3_REG);
  1350. if(ACCOUNT1_REG == REGISTER_OK)
  1351. {
  1352. if(line_id[1] == -1)
  1353. {
  1354. BARESIP_STATUS = IDLE;
  1355. break;
  1356. }
  1357. sprintf(cmd,"{\"cmd\":\"dial\",\"data\":\"%s %d\"}",onekey_num, line_id[1]);
  1358. }
  1359. else if(ACCOUNT2_REG == REGISTER_OK)
  1360. {
  1361. if(line_id[2] == -1)
  1362. {
  1363. BARESIP_STATUS = IDLE;
  1364. break;
  1365. }
  1366. sprintf(cmd,"{\"cmd\":\"dial\",\"data\":\"%s %d\"}",onekey_num, line_id[2]);
  1367. }
  1368. else if(ACCOUNT3_REG == REGISTER_OK)
  1369. {
  1370. if(line_id[3] == -1)
  1371. {
  1372. BARESIP_STATUS = IDLE;
  1373. break;
  1374. }
  1375. sprintf(cmd,"{\"cmd\":\"dial\",\"data\":\"%s %d\"}",onekey_num, line_id[3]);
  1376. }
  1377. else
  1378. {
  1379. BARESIP_STATUS = IDLE;
  1380. break;
  1381. }
  1382. }
  1383. else if (strcmp(onekey_line, "account_info_1") == 0)
  1384. {
  1385. if(line_id[1] == -1 || ACCOUNT1_REG != REGISTER_OK)
  1386. {
  1387. BARESIP_STATUS = IDLE;
  1388. break;
  1389. }
  1390. sprintf(cmd,"{\"cmd\":\"dial\",\"data\":\"%s %d\"}",onekey_num, line_id[1]);
  1391. }
  1392. else if (strcmp(onekey_line, "account_info_2") == 0)
  1393. {
  1394. if(line_id[2] == -1 || ACCOUNT2_REG != REGISTER_OK)
  1395. {
  1396. BARESIP_STATUS = IDLE;
  1397. break;
  1398. }
  1399. sprintf(cmd,"{\"cmd\":\"dial\",\"data\":\"%s %d\"}",onekey_num, line_id[2]);
  1400. }
  1401. else if (strcmp(onekey_line, "account_info_3") == 0)
  1402. {
  1403. if(line_id[3] == -1 || ACCOUNT3_REG != REGISTER_OK)
  1404. {
  1405. BARESIP_STATUS = IDLE;
  1406. break;
  1407. }
  1408. sprintf(cmd,"{\"cmd\":\"dial\",\"data\":\"%s %d\"}",onekey_num, line_id[3]);
  1409. }
  1410. else if(strcmp(onekey_line,"p2p") == 0)
  1411. {
  1412. sprintf(cmd,"{\"cmd\":\"dial\",\"data\":\"%s\"}",onekey_num);
  1413. }
  1414. if(DEBUG)
  1415. printf( "dial [%s]\n", cmd );
  1416. control_cmd(channel, cmd);
  1417. sprintf(strtmp, "%s <%s>", onekey_num, onekey_line);
  1418. writeLog( FUN, "KEY1 Call", strtmp );
  1419. break;
  1420. case RINGING:
  1421. case INUSE:
  1422. GetCmdValue(SPK_CONF, "intercom:repress_1_cancel", repress_cancel, sizeof(repress_cancel));
  1423. if(strcmp(repress_cancel, "yes") == 0){
  1424. strcpy(cmd,"{\"cmd\":\"hangup\",\"data\":\"\"}");
  1425. if(DEBUG)
  1426. printf( "hangup call\n" );
  1427. control_cmd(channel, cmd);
  1428. writeLog( FUN, "KEY1 Hangup", "" );
  1429. }
  1430. break;
  1431. case RING:
  1432. CURRENT_KEY = KEY1;
  1433. strcpy(cmd,"{\"cmd\":\"accept\",\"data\":\"\"}");
  1434. if(DEBUG)
  1435. printf( "answer call\n" );
  1436. control_cmd(channel, cmd);
  1437. writeLog( FUN, "KEY1 Answer", "" );
  1438. break;
  1439. case OFFLINE:
  1440. GetCmdValue(SPK_CONF, "call_action_url:unregistered_enable", enable, sizeof(enable));
  1441. if(strcmp(enable,"yes") == 0)
  1442. {
  1443. GetCmdValue(SPK_CONF, "call_action_url:unregistered_url", url, sizeof(url));
  1444. if(strstr(url,VAR_IP))
  1445. {
  1446. if(get_ip(ipaddr))
  1447. strcpy(url, strrpl(url, VAR_IP, ipaddr));
  1448. }
  1449. if(strstr(url,VAR_MAC))
  1450. {
  1451. if(get_mac(macaddr))
  1452. strcpy(url, strrpl(url, VAR_MAC, macaddr));
  1453. }
  1454. if(strstr(url,VAR_UA))
  1455. {
  1456. GetCmdValue(SPK_CONF, "intercom:onekey_line", onekey_line, sizeof(onekey_line));
  1457. sprintf(strtmp,"%s:username",onekey_line);
  1458. GetCmdValue(SPK_CONF, strtmp, account, sizeof(account));
  1459. strcpy(url, strrpl(url, VAR_UA, account));
  1460. }
  1461. if(strstr(url,VAR_NUM))
  1462. {
  1463. GetCmdValue(SPK_CONF, "intercom:onekey_num", onekey_num, sizeof(onekey_num));
  1464. strcpy(url, strrpl(url, VAR_NUM, onekey_num));
  1465. }
  1466. action_url(url);
  1467. writeLog(FUN, "HTTP Request", url);
  1468. }
  1469. break;
  1470. }
  1471. }
  1472. break;
  1473. case KEY2://处理按键2动作
  1474. if( CURRENT_KEY == UNKEY || CURRENT_KEY == KEY2 )
  1475. {
  1476. switch(BARESIP_STATUS)
  1477. {
  1478. case IDLE:
  1479. CURRENT_KEY = KEY2;
  1480. BARESIP_STATUS = DIALING;
  1481. system("/app/ispeaker-service/bin/ispeakerctl stop_music");
  1482. GetCmdValue(SPK_CONF, "intercom:onekey_2_num", onekey_num, sizeof(onekey_num));
  1483. GetCmdValue(SPK_CONF, "intercom:onekey_2_line", onekey_line, sizeof(onekey_line));
  1484. if(strlen(onekey_num) == 0)
  1485. {
  1486. BARESIP_STATUS = IDLE;
  1487. break;
  1488. }
  1489. get_line(line_id);
  1490. if(strcmp(onekey_line,"auto") == 0)
  1491. {
  1492. if(DEBUG)
  1493. printf("ACCOUNT1 is %d, ACCOUNT2 is %d, ACCOUNT3 is %d\n",ACCOUNT1_REG,ACCOUNT2_REG,ACCOUNT3_REG);
  1494. if(ACCOUNT1_REG == REGISTER_OK)
  1495. {
  1496. if(line_id[1] == -1)
  1497. {
  1498. BARESIP_STATUS = IDLE;
  1499. break;
  1500. }
  1501. sprintf(cmd,"{\"cmd\":\"dial\",\"data\":\"%s %d\"}",onekey_num, line_id[1]);
  1502. }
  1503. else if(ACCOUNT2_REG == REGISTER_OK)
  1504. {
  1505. if(line_id[2] == -1)
  1506. {
  1507. BARESIP_STATUS = IDLE;
  1508. break;
  1509. }
  1510. sprintf(cmd,"{\"cmd\":\"dial\",\"data\":\"%s %d\"}",onekey_num, line_id[2]);
  1511. }
  1512. else if(ACCOUNT3_REG == REGISTER_OK)
  1513. {
  1514. if(line_id[3] == -1)
  1515. {
  1516. BARESIP_STATUS = IDLE;
  1517. break;
  1518. }
  1519. sprintf(cmd,"{\"cmd\":\"dial\",\"data\":\"%s %d\"}",onekey_num, line_id[3]);
  1520. }
  1521. else
  1522. {
  1523. BARESIP_STATUS = IDLE;
  1524. break;
  1525. }
  1526. }
  1527. else if (strcmp(onekey_line, "account_info_1") == 0)
  1528. {
  1529. if(line_id[1] == -1 || ACCOUNT1_REG != REGISTER_OK)
  1530. {
  1531. BARESIP_STATUS = IDLE;
  1532. break;
  1533. }
  1534. sprintf(cmd,"{\"cmd\":\"dial\",\"data\":\"%s %d\"}",onekey_num, line_id[1]);
  1535. }
  1536. else if (strcmp(onekey_line, "account_info_2") == 0)
  1537. {
  1538. if(line_id[2] == -1 || ACCOUNT2_REG != REGISTER_OK)
  1539. {
  1540. BARESIP_STATUS = IDLE;
  1541. break;
  1542. }
  1543. sprintf(cmd,"{\"cmd\":\"dial\",\"data\":\"%s %d\"}",onekey_num, line_id[2]);
  1544. }
  1545. else if (strcmp(onekey_line, "account_info_3") == 0)
  1546. {
  1547. if(line_id[3] == -1 || ACCOUNT3_REG != REGISTER_OK)
  1548. {
  1549. BARESIP_STATUS = IDLE;
  1550. break;
  1551. }
  1552. sprintf(cmd,"{\"cmd\":\"dial\",\"data\":\"%s %d\"}",onekey_num, line_id[3]);
  1553. }
  1554. else if(strcmp(onekey_line,"p2p") == 0)
  1555. {
  1556. sprintf(cmd,"{\"cmd\":\"dial\",\"data\":\"%s\"}",onekey_num);
  1557. }
  1558. if(DEBUG)
  1559. printf( "dial [%s]\n", cmd );
  1560. control_cmd(channel, cmd);
  1561. sprintf(strtmp, "%s <%s>", onekey_num, onekey_line);
  1562. writeLog( FUN, "KEY2 Call", strtmp );
  1563. break;
  1564. case RINGING:
  1565. case INUSE:
  1566. GetCmdValue(SPK_CONF, "intercom:repress_2_cancel", repress_cancel, sizeof(repress_cancel));
  1567. if(strcmp(repress_cancel, "yes") == 0){
  1568. strcpy(cmd,"{\"cmd\":\"hangup\",\"data\":\"\"}");
  1569. if(DEBUG)
  1570. printf( "hangup call\n" );
  1571. control_cmd(channel, cmd);
  1572. writeLog( FUN, "KEY2 Hangup", "" );
  1573. }
  1574. break;
  1575. case RING:
  1576. CURRENT_KEY = KEY2;
  1577. strcpy(cmd,"{\"cmd\":\"accept\",\"data\":\"\"}");
  1578. if(DEBUG)
  1579. printf( "answer call\n" );
  1580. control_cmd(channel, cmd);
  1581. writeLog( FUN, "KEY2 Answer", "" );
  1582. break;
  1583. case OFFLINE:
  1584. GetCmdValue(SPK_CONF, "call_action_url:unregistered_enable", enable, sizeof(enable));
  1585. if(strcmp(enable,"yes") == 0)
  1586. {
  1587. GetCmdValue(SPK_CONF, "call_action_url:unregistered_url", url, sizeof(url));
  1588. if(strstr(url,VAR_IP))
  1589. {
  1590. if(get_ip(ipaddr))
  1591. strcpy(url, strrpl(url, VAR_IP, ipaddr));
  1592. }
  1593. if(strstr(url,VAR_MAC))
  1594. {
  1595. if(get_mac(macaddr))
  1596. strcpy(url, strrpl(url, VAR_MAC, macaddr));
  1597. }
  1598. if(strstr(url,VAR_UA))
  1599. {
  1600. GetCmdValue(SPK_CONF, "intercom:onekey_line", onekey_line, sizeof(onekey_line));
  1601. sprintf(strtmp,"%s:username",onekey_line);
  1602. GetCmdValue(SPK_CONF, strtmp, account, sizeof(account));
  1603. strcpy(url, strrpl(url, VAR_UA, account));
  1604. }
  1605. if(strstr(url,VAR_NUM))
  1606. {
  1607. GetCmdValue(SPK_CONF, "intercom:onekey_num", onekey_num, sizeof(onekey_num));
  1608. strcpy(url, strrpl(url, VAR_NUM, onekey_num));
  1609. }
  1610. action_url(url);
  1611. writeLog(FUN, "HTTP Request", url);
  1612. }
  1613. break;
  1614. }
  1615. }
  1616. break;
  1617. case KEY3:
  1618. system("/etc/scripts/play_rebooting.sh");
  1619. system("rm -f /oem/.userdata && /sbin/reboot");
  1620. break;
  1621. case KEY4_3:
  1622. PlayIP();
  1623. break;
  1624. case KEY4_10:
  1625. system("/etc/scripts/play_rebooting.sh 1");
  1626. system("/sbin/reboot");
  1627. break;
  1628. }
  1629. }
  1630. void *checkReg()
  1631. {
  1632. dictionary * ini ;
  1633. ini = iniparser_load(SPK_CONF);
  1634. if (ini==NULL) {
  1635. fprintf(stderr, "cannot parse file: %s\n", SPK_CONF);
  1636. return FALSE;
  1637. }
  1638. if((strcmp(iniparser_getstring(ini, "account_info_1:enable", "no"), "yes") == 0 || strcmp(iniparser_getstring(ini, "account_info_2:enable", "no"), "yes") == 0 ||
  1639. strcmp(iniparser_getstring(ini, "account_info_3:enable", "no"), "yes") == 0) && regcount == 0)
  1640. {
  1641. system("/etc/scrtips/sipphone.sh stop");
  1642. }
  1643. regcount = 0;
  1644. iniparser_freedict(ini);
  1645. }
  1646. //根据不同的业务状态点灯
  1647. void *led_status()
  1648. {
  1649. int ledFlashTime = 0,led1FlashTag1 = 0,led1FlashTag2 = 0,led2FlashTag1 = 0,led2FlashTag2 = 0, count = 0;
  1650. pthread_t thread1;
  1651. while(1)
  1652. {
  1653. usleep(10 * 1000);
  1654. /* led flash controller */
  1655. ledFlashTime++;
  1656. if(ledFlashTime == 47 || ledFlashTime == 143){
  1657. if(key1LedStatus == Led_On)
  1658. system("echo 0 > /sys/class/gpio/gpio130/value");
  1659. else if(key1LedStatus == Led_Off)
  1660. system("echo 1 > /sys/class/gpio/gpio130/value");
  1661. if(key2LedStatus == Led_On)
  1662. system("echo 0 > /sys/class/gpio/gpio131/value");
  1663. else if(key2LedStatus == Led_Off)
  1664. system("echo 1 > /sys/class/gpio/gpio131/value");
  1665. }
  1666. if(ledFlashTime % 19 == 0){
  1667. if(key1LedStatus == Led_Fast){
  1668. led1FlashTag1 = !led1FlashTag1;
  1669. if(led1FlashTag1){
  1670. system("echo 0 > /sys/class/gpio/gpio130/value");
  1671. }else{
  1672. system("echo 1 > /sys/class/gpio/gpio130/value");
  1673. }
  1674. }
  1675. if(key2LedStatus == Led_Fast){
  1676. led2FlashTag1 = !led2FlashTag1;
  1677. if(led2FlashTag1){
  1678. system("echo 0 > /sys/class/gpio/gpio131/value");
  1679. }else{
  1680. system("echo 1 > /sys/class/gpio/gpio131/value");
  1681. }
  1682. }
  1683. }
  1684. if(ledFlashTime % 99 == 0){
  1685. if(key1LedStatus == Led_Slow){
  1686. led1FlashTag2 = !led1FlashTag2;
  1687. if(led1FlashTag2){
  1688. system("echo 0 > /sys/class/gpio/gpio130/value");
  1689. }else{
  1690. system("echo 1 > /sys/class/gpio/gpio130/value");
  1691. }
  1692. }
  1693. if(key2LedStatus == Led_Slow){
  1694. led2FlashTag2 = !led2FlashTag2;
  1695. if(led2FlashTag2){
  1696. system("echo 0 > /sys/class/gpio/gpio131/value");
  1697. }else{
  1698. system("echo 1 > /sys/class/gpio/gpio131/value");
  1699. }
  1700. }
  1701. }
  1702. /* restart the led flash loop */
  1703. if(ledFlashTime == 200)
  1704. {
  1705. ledFlashTime = 0;
  1706. }
  1707. }
  1708. }
  1709. void reset_vlcInfo(int id)
  1710. {
  1711. vlcInfo[id].pid = 0;
  1712. vlcInfo[id].prio = 0;
  1713. memset(vlcInfo->param, 0, sizeof(vlcInfo->param));
  1714. }
  1715. int file_exists(char *filename)
  1716. {
  1717. return (access(filename, 0) == 0);
  1718. }
  1719. int vlc_cmd_action(char *action, int id)
  1720. {
  1721. char cmd[128], ctrlfile[32];
  1722. int i = 0;
  1723. sprintf(ctrlfile,"/tmp/vlc_%d.sock",id);
  1724. while(i < MAX_TRY)
  1725. {
  1726. if(file_exists(ctrlfile))
  1727. {
  1728. sprintf(cmd,"echo \"%s\" | socat - unix-connect:%s", action, ctrlfile);
  1729. if(DEBUG) printf("volume CMD: %s\n", cmd);
  1730. if(system(cmd) == 0)
  1731. return TRUE;
  1732. else
  1733. continue;
  1734. }
  1735. usleep(200*1000);
  1736. i ++;
  1737. }
  1738. return FALSE;
  1739. }
  1740. int schedule_start_check_prio(int prio)
  1741. {
  1742. char cmd[64];
  1743. for(int i = 1; i < 31; i++)
  1744. {
  1745. if(DEBUG)
  1746. printf("==============%d,%d,%d,%s=============\n", i, SCHEDULE[i], vlcInfo[i].prio, vlcInfo[i].param);
  1747. if(SCHEDULE[i] != STOP)
  1748. {
  1749. if(prio < vlcInfo[i].prio)
  1750. return FALSE;
  1751. else if(SCHEDULE[i] == RUNNING && prio > vlcInfo[i].prio)
  1752. {
  1753. if(vlc_cmd_action("pause",i))
  1754. SCHEDULE[i] = PAUSED;
  1755. }
  1756. }
  1757. }
  1758. return TRUE;
  1759. }
  1760. void schedule_stop_check_prio(int prio)
  1761. {
  1762. char cmd[64];
  1763. int paused[30],running[30],c_paused = 0, c_running = 0;
  1764. int isRunning = FALSE;
  1765. for(int i = 1; i < 31; i++)
  1766. {
  1767. if(SCHEDULE[i] == RUNNING)
  1768. {
  1769. return;
  1770. }
  1771. if(SCHEDULE[i] == PAUSED)
  1772. {
  1773. paused[c_paused] = i;
  1774. c_paused ++;
  1775. }
  1776. }
  1777. for(int p = prio; p > 0; p--)
  1778. {
  1779. for(int n = 0; n < c_paused; n++)
  1780. {
  1781. if(p == vlcInfo[paused[n]].prio)
  1782. {
  1783. state_event(AUDIO_ON);
  1784. if(vlc_cmd_action("pause",paused[n]))
  1785. {
  1786. SCHEDULE[paused[n]] = RUNNING;
  1787. isRunning = TRUE;
  1788. }
  1789. }
  1790. }
  1791. if(isRunning) return;
  1792. }
  1793. state_event(AUDIO_OFF);
  1794. }
  1795. void playAudio(int id, int times, int isBeep, char *enSrceen, char *file, int prio, int vol)
  1796. {
  1797. char filetmp[64], action[128], sockio[32], paused[32],loop[16],cmd[64], gain[32];
  1798. int status, isPaused;
  1799. bzero(paused,sizeof(paused));
  1800. if(!schedule_start_check_prio(prio))
  1801. {
  1802. strcpy(paused,"--start-paused");
  1803. isPaused = TRUE;
  1804. }
  1805. else
  1806. {
  1807. strcpy(paused,"--no-start-paused");
  1808. isPaused = FALSE;
  1809. state_event(AUDIO_ON);
  1810. }
  1811. if(times == 0)
  1812. {
  1813. sprintf(filetmp, "/usr/share/baresip/%s", file);
  1814. strcpy(loop,"--loop");
  1815. }
  1816. else
  1817. {
  1818. sprintf(filetmp,"/tmp/playlist_%d.m3u",id);
  1819. FILE *fd = fopen(filetmp, "w+");
  1820. if(fd == NULL)
  1821. {
  1822. if(DEBUG) printf("play failed!\n");
  1823. return;
  1824. }
  1825. if(isBeep) fprintf(fd,"/usr/share/baresip/s_beep.mp3\n");
  1826. for(int i=0;i<times;i++)
  1827. {
  1828. fprintf(fd,"/usr/share/baresip/%s\n",file);
  1829. }
  1830. if(isBeep) fprintf(fd,"/usr/share/baresip/e_beep.mp3\n");
  1831. fclose(fd);
  1832. strcpy(loop,"--no-loop");
  1833. }
  1834. sprintf(gain, "--gain=%.02f", (float) vol/100);
  1835. sprintf(sockio,"--rc-unix=/tmp/vlc_%d.sock", id);
  1836. char *argv[] = {"vlc","--play-and-exit","--control","rc","--rc-fake-tty",sockio,paused,loop,gain,filetmp,NULL};
  1837. status = posix_spawn(&vlcInfo[id].pid,"/usr/sbin/vlc",NULL,NULL,argv,NULL);
  1838. if(status == 0)
  1839. {
  1840. usleep(300*1000);
  1841. // sprintf(action,"volume %d", 256 * vol/100);
  1842. // vlc_cmd_action(action,id);
  1843. SCHEDULE[id] = (isPaused)?PAUSED:RUNNING;
  1844. vlcInfo[id].prio = prio;
  1845. sprintf(vlcInfo[id].param,"%s", file);
  1846. sprintf(action,"Play audio: %s", vlcInfo[id].param);
  1847. writeLog(FUN, "Audio Control", action);
  1848. //system("echo 0 > /sys/class/gpio/gpio5/value");
  1849. if(waitpid(vlcInfo[id].pid, &status, 0) != -1)
  1850. {
  1851. if(DEBUG) printf("Child exited with status %i\n", status);
  1852. SCHEDULE[id] = STOP;
  1853. schedule_stop_check_prio(vlcInfo[id].prio);
  1854. reset_vlcInfo(id);
  1855. if(strcmp(enSrceen, "Disabled") != 0)
  1856. {
  1857. sprintf(cmd,"{\"action\": \"off\", \"id\": %s}", enSrceen);
  1858. screen_control(cmd);
  1859. }
  1860. //system("echo 1 > /sys/class/gpio/gpio5/value");
  1861. sprintf(action,"Stop audio: %s", vlcInfo[id].param);
  1862. writeLog(FUN, "Audio Control", action);
  1863. }
  1864. }
  1865. if(times) remove(filetmp);
  1866. }
  1867. void *handle_playAudio(void *arg)
  1868. {
  1869. int selfkey, isBeep = FALSE, times = 0;
  1870. PlayInfo *p = arg;
  1871. selfkey = p->key_id;
  1872. if(strlen(p->times_str)) times = atoi(p->times_str);
  1873. if(strcmp(p->enBeep, "yes") == 0) isBeep = TRUE;
  1874. if(strlen(p->file))
  1875. {
  1876. playAudio(selfkey, times, isBeep, p->enSrceen, p->file, p->prio, p->vol);
  1877. }
  1878. free(p);
  1879. }
  1880. int equalDate(struct date A,struct date B)
  1881. {
  1882. if(A.year==B.year && A.month==B.month && A.day==B.day)
  1883. return TRUE;
  1884. return FALSE;
  1885. }
  1886. int compareDate(struct date A,struct date B)
  1887. {
  1888. if(A.year<B.year)
  1889. return TRUE;
  1890. if(A.year==B.year && A.month<B.month)
  1891. return TRUE;
  1892. if(A.year==B.year && A.month==B.month && A.day<B.day)
  1893. return TRUE;
  1894. return FALSE;
  1895. }
  1896. void date_format(char *date_str, struct date *s_holiday, struct date *e_holiday)
  1897. {
  1898. struct date date;
  1899. sscanf(date_str, "%d-%d-%d:%d-%d-%d", &s_holiday->year, &s_holiday->month, &s_holiday->day, &e_holiday->year, &e_holiday->month, &e_holiday->day);
  1900. }
  1901. int isHoliday(struct date currDate, char *holidays)
  1902. {
  1903. cJSON *pJson, *pSub;
  1904. struct date s_holiday, e_holiday;
  1905. pJson = cJSON_Parse(holidays);
  1906. if (pJson)
  1907. {
  1908. cJSON *holidaysArray = cJSON_GetObjectItem( pJson, "holidays");
  1909. if(holidaysArray != NULL)
  1910. {
  1911. int array_size = cJSON_GetArraySize (holidaysArray);
  1912. for(int n = 0; n < array_size; n++)
  1913. {
  1914. pSub = cJSON_GetArrayItem(holidaysArray, n);
  1915. date_format(pSub->valuestring, &s_holiday, &e_holiday);
  1916. if(DEBUG)
  1917. {
  1918. printf("current date: %d-%d-%d\n",currDate.year, currDate.month, currDate.day);
  1919. printf("holiday start: %d-%d-%d\n",s_holiday.year, s_holiday.month, s_holiday.day);
  1920. printf("holiday end: %d-%d-%d\n",e_holiday.year, e_holiday.month, e_holiday.day);
  1921. }
  1922. if(equalDate(currDate, s_holiday) || (compareDate(s_holiday, currDate) && compareDate(currDate, e_holiday)))
  1923. {
  1924. cJSON_Delete(pJson);
  1925. return TRUE;
  1926. }
  1927. }
  1928. }
  1929. }
  1930. cJSON_Delete(pJson);
  1931. return FALSE;
  1932. }
  1933. void schedule(int year, int month, int day, int hour, int minute, int week)
  1934. {
  1935. char actiontype[32], keyaction[16], keyactiontype[32], type[16], action_type[16];
  1936. char keystr[32],enable[8],weeks[8], enholiday[8], holidays[4096];
  1937. char w[4],action[128],screen_id[16];
  1938. int s_hour, e_hour, s_min, e_min;
  1939. int s_time, e_time, time, interval;
  1940. struct date s_date, e_date, date;
  1941. dictionary * ini ;
  1942. date.year = year;
  1943. date.month = month;
  1944. date.day = day;
  1945. ini = iniparser_load(SCHEDULE_CONF);
  1946. if (ini==NULL) {
  1947. fprintf(stderr, "cannot parse file: %s\n", SCHEDULE_CONF);
  1948. return;
  1949. }
  1950. strcpy(holidays, iniparser_getstring(ini, "holidays:data", "{\"holidays\": []}"));
  1951. for(int i=1;i<31;i++)
  1952. {
  1953. sprintf(keystr,"schedule_%d:enable",i);
  1954. strcpy(enable, iniparser_getstring(ini, keystr, "no"));
  1955. if(strcmp(enable,"yes") == 0)
  1956. {
  1957. sprintf(keystr,"schedule_%d:enholiday",i);
  1958. strcpy(enholiday, iniparser_getstring(ini, keystr, "no"));
  1959. if(strcmp(enholiday, "yes") == 0 && isHoliday(date, holidays)) continue;
  1960. sprintf(keystr,"schedule_%d:weeks",i);
  1961. strcpy(weeks, iniparser_getstring(ini, keystr, ""));
  1962. sprintf(w,"%d",week);
  1963. if(strchr(weeks,w[0]) == NULL) continue;
  1964. sprintf(keystr,"schedule_%d:s_year",i);
  1965. s_date.year = iniparser_getint(ini, keystr, 0);
  1966. sprintf(keystr,"schedule_%d:e_year",i);
  1967. e_date.year = iniparser_getint(ini, keystr, 0);
  1968. sprintf(keystr,"schedule_%d:s_month",i);
  1969. s_date.month = iniparser_getint(ini, keystr, 0);
  1970. sprintf(keystr,"schedule_%d:e_month",i);
  1971. e_date.month = iniparser_getint(ini, keystr, 0);
  1972. sprintf(keystr,"schedule_%d:s_day",i);
  1973. s_date.day = iniparser_getint(ini, keystr, 0);
  1974. sprintf(keystr,"schedule_%d:e_day",i);
  1975. e_date.day = iniparser_getint(ini, keystr, 0);
  1976. if(compareDate(date, s_date) || compareDate(e_date, date)) continue;
  1977. sprintf(keystr,"schedule_%d:s_hour",i);
  1978. s_hour = iniparser_getint(ini, keystr, 0);
  1979. sprintf(keystr,"schedule_%d:e_hour",i);
  1980. e_hour = iniparser_getint(ini, keystr, 0);
  1981. sprintf(keystr,"schedule_%d:s_min",i);
  1982. s_min = iniparser_getint(ini, keystr, 0);
  1983. sprintf(keystr,"schedule_%d:e_min",i);
  1984. e_min = iniparser_getint(ini, keystr, 0);
  1985. sprintf(keystr,"schedule_%d:interval",i);
  1986. interval = iniparser_getint(ini, keystr, 60);
  1987. sprintf(keystr,"schedule_%d:trigger_screen",i);
  1988. strcpy(screen_id, iniparser_getstring(ini, keystr, "Disabled"));
  1989. time = hour * 60 + minute;
  1990. s_time = s_hour * 60 + s_min;
  1991. e_time = e_hour * 60 + e_min;
  1992. if(time >= s_time && time <= e_time)
  1993. {
  1994. if(time == e_time)
  1995. {
  1996. sprintf(keystr,"%d",i);
  1997. writeLog(SCHED, keystr, "Executed");
  1998. if(SCHEDULE[i] == RUNNING)
  1999. {
  2000. char strtmp[64],cmd[128];
  2001. if(strcmp(screen_id, "Disabled") != 0)
  2002. {
  2003. sprintf(strtmp,"{\"action\": \"off\", \"id\": %s}", screen_id);
  2004. screen_control(strtmp);
  2005. }
  2006. sprintf(cmd,"kill -9 %d",vlcInfo[i].pid);
  2007. system(cmd);
  2008. // system("echo 1 > /sys/class/gpio/gpio5/value");
  2009. // SCHEDULE[i] = STOP;
  2010. // sprintf(action,"Stop audio: %s", vlcInfo[i].param);
  2011. // writeLog(FUN, "Audio Control", action);
  2012. }
  2013. continue;
  2014. }
  2015. if((interval != 0 && (time - s_time) % interval == 0) || (interval == 0 && time == s_time))
  2016. {
  2017. sprintf(keystr,"%d",i);
  2018. writeLog(SCHED, keystr, "Executed");
  2019. char cmd[256], strtmp[64], source[16];
  2020. pthread_t thread_audio;
  2021. int ret_thrd;
  2022. if(SCHEDULE[i] == STOP)
  2023. {
  2024. PlayInfo *playAudioInfo = malloc(sizeof(PlayInfo));
  2025. playAudioInfo->key_id = i;
  2026. bzero(strtmp, sizeof(strtmp));
  2027. sprintf(strtmp,"schedule_%d:source",i);
  2028. strcpy(source, iniparser_getstring(ini, strtmp, ""));
  2029. bzero(strtmp, sizeof(strtmp));
  2030. sprintf(strtmp, "schedule_%d:audio_file", i);
  2031. strcpy(playAudioInfo->file, iniparser_getstring(ini, strtmp, ""));
  2032. bzero(strtmp, sizeof(strtmp));
  2033. sprintf(strtmp,"schedule_%d:play_times",i);
  2034. strcpy(playAudioInfo->times_str, iniparser_getstring(ini, strtmp, ""));
  2035. bzero(strtmp, sizeof(strtmp));
  2036. sprintf(strtmp,"schedule_%d:enBeep",i);
  2037. strcpy(playAudioInfo->enBeep, iniparser_getstring(ini, strtmp, "no"));
  2038. strcpy(playAudioInfo->enSrceen, screen_id);
  2039. bzero(strtmp, sizeof(strtmp));
  2040. sprintf(strtmp,"schedule_%d:priority",i);
  2041. playAudioInfo->prio = iniparser_getint(ini, strtmp, 1);
  2042. bzero(strtmp, sizeof(strtmp));
  2043. sprintf(strtmp,"schedule_%d:volume",i);
  2044. playAudioInfo->vol = iniparser_getint(ini, strtmp, 100);
  2045. if(strcmp(screen_id, "Disabled") != 0)
  2046. {
  2047. sprintf(strtmp,"{\"action\": \"on\", \"id\": %s}", screen_id);
  2048. screen_control(strtmp);
  2049. }
  2050. ret_thrd = pthread_create(&thread_audio, NULL, handle_playAudio, playAudioInfo);
  2051. if (ret_thrd != 0)
  2052. {
  2053. printf("create thread1 handle_playAudio failed\n");
  2054. free(playAudioInfo);
  2055. continue;
  2056. }
  2057. pthread_detach(thread_audio);
  2058. }
  2059. else
  2060. {
  2061. if(strcmp(screen_id, "Disabled") != 0)
  2062. {
  2063. sprintf(strtmp,"{\"action\": \"off\", \"id\": %s}", screen_id);
  2064. screen_control(strtmp);
  2065. }
  2066. sprintf(cmd,"kill -9 %d",vlcInfo[i].pid);
  2067. system(cmd);
  2068. // system("echo 1 > /sys/class/gpio/gpio5/value");
  2069. // SCHEDULE[i] = STOP;
  2070. // sprintf(action,"Stop audio: %s", vlcInfo[i].param);
  2071. // writeLog(FUN, "Audio Control", action);
  2072. }
  2073. }
  2074. }
  2075. }
  2076. }
  2077. iniparser_freedict(ini);
  2078. }
  2079. void *handleDateTime()
  2080. {
  2081. time_t nSeconds;
  2082. struct tm *pTM;
  2083. int year, month, hour, count;
  2084. pthread_t thread1;
  2085. while(1)
  2086. {
  2087. time(&nSeconds);
  2088. pTM = localtime(&nSeconds);
  2089. if(pTM->tm_sec == 0)
  2090. {
  2091. year = pTM->tm_year + 1900;
  2092. month = pTM->tm_mon + 1;
  2093. schedule(year, month, pTM->tm_mday, pTM->tm_hour, pTM->tm_min, pTM->tm_wday);
  2094. count ++;
  2095. if(count > 120)
  2096. {
  2097. pthread_create(&thread1, NULL, checkReg, NULL);
  2098. pthread_detach(thread1);
  2099. count = 0;
  2100. }
  2101. }
  2102. sleep(1);
  2103. }
  2104. }
  2105. //解析音量设置数据
  2106. void ProcessVolumeReply( redisReply * pReply )
  2107. {
  2108. cJSON *pJson = NULL;
  2109. redisReply * pSubReply = NULL;
  2110. char cmd[MAX_PIPE_BUFSIZE];
  2111. int channel = BARESIP_CHAN;
  2112. if ( pReply != NULL && pReply->elements == 3 )
  2113. {
  2114. pSubReply = pReply->element[2];
  2115. pJson = cJSON_Parse(pSubReply->str);
  2116. if ( pJson ) {
  2117. if(cJSON_GetObjectItem(pJson, "audio_volume"))
  2118. {
  2119. if(cJSON_GetObjectItem(pJson, "audio_volume")->valueint == 0)
  2120. schedule_start_check_prio(MAX_PRIORITY + 1);
  2121. else
  2122. schedule_stop_check_prio(MAX_PRIORITY + 1);
  2123. }
  2124. }else{
  2125. printf( "parse failed!\n");
  2126. }
  2127. if(pJson != NULL) cJSON_Delete(pJson);
  2128. }
  2129. }
  2130. /*
  2131. * 订阅音量信息.
  2132. */
  2133. void *get_volume_info()
  2134. {
  2135. redisContext * pContext = redisConnectUnix(unix_socket_path);
  2136. if ( NULL == pContext || pContext->err == 1 )
  2137. {
  2138. printf( "%s\n", pContext->errstr );
  2139. exit( -1 );
  2140. }
  2141. char * pKey = "volume-value-channel";
  2142. redisReply * pReply = redisCommand( pContext, "SUBSCRIBE %s", pKey );
  2143. freeReplyObject( pReply );
  2144. while ( redisGetReply( pContext, (void **)&pReply ) == REDIS_OK )
  2145. {
  2146. ProcessVolumeReply( pReply );
  2147. freeReplyObject( pReply );
  2148. }
  2149. redisFree( pContext );
  2150. }
  2151. void play_audio(char *audiofile, int repeat)
  2152. {
  2153. char cmd[320];
  2154. int channel = BARESIP_CHAN;
  2155. sprintf(cmd,"{\"cmd\":\"play\",\"data\":\"%s:%d\"}",audiofile,repeat);
  2156. control_cmd(channel, cmd);
  2157. }
  2158. const int get_sip_status(char *accountaor)
  2159. {
  2160. int status = OFFLINE;
  2161. const int id = redis_pool_get_context(redisClient);
  2162. if (id != -1) {
  2163. redisReply *reply = NULL;
  2164. reply = (redisReply *) redisCommand(redisClient->context[id], "GET %s", accountaor);
  2165. if (reply && reply->type == REDIS_REPLY_STRING) {
  2166. // 处理回复
  2167. if(DEBUG) printf("SIP acc: %s, status: %s\n", accountaor, reply->str);
  2168. if(strcmp(reply->str, "{\"status\":\"idle\"}") == 0)
  2169. {
  2170. status = IDLE;
  2171. }
  2172. else if(strcmp(reply->str, "{\"status\":\"answer\"}") == 0)
  2173. {
  2174. status = INUSE;
  2175. }
  2176. else if(strcmp(reply->str, "{\"status\":\"ringing\"}") == 0)
  2177. {
  2178. status = RINGING;
  2179. }
  2180. else if(strcmp(reply->str, "{\"status\":\"ring\"}") == 0)
  2181. {
  2182. status = RING;
  2183. }
  2184. }
  2185. if(reply != NULL) freeReplyObject(reply);
  2186. redis_pool_release_connection(redisClient, id);
  2187. }
  2188. if(BARESIP_STATUS == OFFLINE || BARESIP_STATUS == IDLE)
  2189. BARESIP_STATUS = status;
  2190. return status;
  2191. }
  2192. void sip_reg_status_init()
  2193. {
  2194. //初始化SIP注册状态
  2195. char enac1[8],enac2[8],enac3[8],p2penable[8],accountaor1[192], accountaor2[192], accountaor3[192];
  2196. char account1[32], domain1[128], account2[32], domain2[128], account3[32], domain3[128];
  2197. GetCmdValue(SPK_CONF, "account_info_1:enable", enac1, sizeof(enac1));
  2198. if(strcmp(enac1, "yes") == 0)
  2199. {
  2200. GetCmdValue(SPK_CONF, "account_info_1:username", account1, sizeof(account1));
  2201. GetCmdValue(SPK_CONF, "account_info_1:domain", domain1, sizeof(domain1));
  2202. if(strlen(domain1) == 0)
  2203. {
  2204. GetCmdValue(SPK_CONF, "account_info_1:server", domain1, sizeof(domain1));
  2205. }
  2206. memset(accountaor1, '\0', sizeof(accountaor1));
  2207. sprintf(accountaor1, "baresip-call-status-%s-%s", account1, domain1);
  2208. if(get_sip_status(accountaor1) != OFFLINE)
  2209. {
  2210. ACCOUNT1_REG = REGISTER_OK;
  2211. }
  2212. }
  2213. GetCmdValue(SPK_CONF, "account_info_2:enable", enac2, sizeof(enac2));
  2214. if(strcmp(enac2, "yes") == 0)
  2215. {
  2216. GetCmdValue(SPK_CONF, "account_info_2:username", account2, sizeof(account2));
  2217. GetCmdValue(SPK_CONF, "account_info_2:domain", domain2, sizeof(domain2));
  2218. if(strlen(domain2) == 0)
  2219. {
  2220. GetCmdValue(SPK_CONF, "account_info_2:server", domain2, sizeof(domain2));
  2221. }
  2222. memset(accountaor2, '\0', sizeof(accountaor2));
  2223. sprintf(accountaor2, "baresip-call-status-%s-%s", account2, domain2);
  2224. if(get_sip_status(accountaor2) != OFFLINE)
  2225. {
  2226. ACCOUNT2_REG = REGISTER_OK;
  2227. }
  2228. }
  2229. GetCmdValue(SPK_CONF, "account_info_3:enable", enac3, sizeof(enac3));
  2230. if(strcmp(enac3, "yes") == 0)
  2231. {
  2232. GetCmdValue(SPK_CONF, "account_info_3:username", account3, sizeof(account3));
  2233. GetCmdValue(SPK_CONF, "account_info_3:domain", domain3, sizeof(domain3));
  2234. if(strlen(domain3) == 0)
  2235. {
  2236. GetCmdValue(SPK_CONF, "account_info_3:server", domain3, sizeof(domain3));
  2237. }
  2238. memset(accountaor3, '\0', sizeof(accountaor3));
  2239. sprintf(accountaor3, "baresip-call-status-%s-%s", account3, domain3);
  2240. if(get_sip_status(accountaor3) != OFFLINE)
  2241. {
  2242. ACCOUNT3_REG = REGISTER_OK;
  2243. }
  2244. }
  2245. GetCmdValue(SPK_CONF, "account_info_p2p:enable", p2penable, sizeof(p2penable));
  2246. if(strcmp(p2penable,"yes") == 0)
  2247. {
  2248. ACCOUNTP2P_REG = REGISTER_OK;
  2249. }
  2250. if(ACCOUNT1_REG == REGISTER_OK || ACCOUNT2_REG == REGISTER_OK || ACCOUNT3_REG == REGISTER_OK || ACCOUNTP2P_REG == REGISTER_OK)
  2251. {
  2252. key1LedStatus = Led_On;
  2253. key2LedStatus = Led_On;
  2254. }
  2255. }
  2256. const int init()
  2257. {
  2258. int ret_thrd1,ret_thrd2,ret_thrd3,ret_thrd4,ret_thrd5;
  2259. pthread_t thread1, thread2, thread3, thread4, thread5;
  2260. redisClient = create_redis_pool_client(unix_socket_path);
  2261. memset(SCHEDULE, 0,sizeof(SCHEDULE));
  2262. sip_reg_status_init();
  2263. //启动线程订阅BARESIP实时状态
  2264. ret_thrd1 = pthread_create(&thread1, NULL, baresip_status, NULL);
  2265. if (ret_thrd1 != 0) {
  2266. printf("create thread1 baresip_status failed\n");
  2267. return FALSE;
  2268. }
  2269. //启动线程根据不同的业务状态点亮状态指示灯
  2270. ret_thrd2 = pthread_create(&thread2, NULL, led_status, NULL);
  2271. if (ret_thrd2 != 0) {
  2272. printf("create thread2 led_status failed\n");
  2273. return FALSE;
  2274. }
  2275. //启动日志记录线程
  2276. ret_thrd3 = pthread_create(&thread3, NULL, write_opnlog, NULL);
  2277. if (ret_thrd3 != 0) {
  2278. printf("create thread3 write_opnlog failed\n");
  2279. return FALSE;
  2280. }
  2281. //启动系统时间显示线程
  2282. ret_thrd4 = pthread_create(&thread4, NULL, handleDateTime, NULL);
  2283. if (ret_thrd4 != 0)
  2284. {
  2285. printf("create thread4 handleDateTime failed\n");
  2286. return FALSE;
  2287. }
  2288. //启动线程订阅音量设置
  2289. ret_thrd5 = pthread_create(&thread5, NULL, get_volume_info, NULL);
  2290. if (ret_thrd5 != 0) {
  2291. printf("create thread5 get_volume_info failed\n");
  2292. return FALSE;
  2293. }
  2294. return TRUE;
  2295. }
  2296. int main(int argc, char *argv[]){
  2297. struct pollfd fdset[2];
  2298. int switch_fd,reset_fd,ret;
  2299. int len, count, i, key1_action, key2_action;
  2300. char buf[8], strtmp[64],action[8],url[256], srceen[8], type[16], input[8];
  2301. time_t lastime, newtime;
  2302. if(argc == 2 && strcmp(argv[1], "debug") == 0)
  2303. DEBUG = TRUE;
  2304. if(!init())
  2305. {
  2306. printf("init failed!\n");
  2307. exit( -1 );
  2308. }
  2309. /* SWITCH */
  2310. switch_fd = open("/sys/class/gpio/gpio111/value", O_RDONLY);
  2311. read(switch_fd, buf, sizeof(buf));
  2312. lseek(switch_fd, 0, SEEK_SET);
  2313. /* RESET */
  2314. reset_fd = open("/sys/class/gpio/gpio73/value", O_RDONLY);
  2315. read(reset_fd, buf, sizeof(buf));
  2316. lseek(reset_fd, 0, SEEK_SET);
  2317. while(1)
  2318. {
  2319. memset(fdset, 0x00, sizeof(struct pollfd) * 2);
  2320. fdset[0].fd = switch_fd;
  2321. fdset[0].events = POLLPRI;
  2322. fdset[1].fd = reset_fd;
  2323. fdset[1].events = POLLPRI;
  2324. ret = poll(fdset, 2, 3000);
  2325. if(ret < 0){
  2326. printf("npoll() faild! \n");
  2327. return -1;
  2328. }
  2329. if(ret == 0)
  2330. continue;
  2331. /*SWITCH*/
  2332. if( fdset[0].revents & POLLPRI )
  2333. {
  2334. count = 0;
  2335. for(i=0;i<100;i++){ // 100ms
  2336. bzero(buf,sizeof(buf));
  2337. read(fdset[0].fd, buf, sizeof(buf));
  2338. lseek(fdset[0].fd, 0, SEEK_SET);
  2339. if(buf[0]-'0' == 0)
  2340. count++;
  2341. usleep(1000);
  2342. }
  2343. // printf("zero counts: %d\n", count);
  2344. if (count >= 70) {
  2345. GetCmdValue(SPK_CONF, "intercom:type", type, sizeof(type));
  2346. GetCmdValue(SPK_CONF, "trigger:input", input, sizeof(input));
  2347. if(strcmp(type,"key") == 0)
  2348. {
  2349. playBeep();
  2350. printf("KEY DOWN\n");
  2351. writeLog(BTN, "KEY", "Click");
  2352. char action[8],url[256];
  2353. GetCmdValue(SPK_CONF, "intercom:key_action", action, sizeof(action));
  2354. if(strcmp(action,"call") == 0)
  2355. {
  2356. outgoingCall(KEY);
  2357. }
  2358. else if(strcmp(action,"http") == 0)
  2359. {
  2360. GetCmdValue(SPK_CONF, "intercom:http_url", url, sizeof(url));
  2361. action_url(url);
  2362. writeLog(FUN, "KEY HTTP Request", url);
  2363. }
  2364. else if(strcmp(action,"play") == 0)
  2365. {
  2366. char audiofile[32],repeat_tmp[16];
  2367. GetCmdValue(SPK_CONF, "intercom:audio_file", audiofile, sizeof(audiofile));
  2368. GetCmdValue(SPK_CONF, "intercom:audio_repeat", repeat_tmp, sizeof(repeat_tmp));
  2369. int repeat = atoi(repeat_tmp);
  2370. play_audio(audiofile,repeat);
  2371. sprintf(strtmp, "File: %s; Repeat: %d", audiofile, repeat);
  2372. writeLog( FUN, "KEY Play Auido", strtmp );
  2373. }
  2374. if(strcmp(input,"key") == 0)
  2375. {
  2376. outputControl(GPIO_135, GPIO_ON);
  2377. if(DEBUG)
  2378. printf( "gpio135 set on\n" );
  2379. //gpio触发后判断是否为延时复位
  2380. pthread_t thread_delay;
  2381. pthread_create(&thread_delay, NULL, gpioDelayControl, NULL);
  2382. pthread_detach(thread_delay);
  2383. }
  2384. }
  2385. else if(strcmp(type,"switch") == 0)
  2386. {
  2387. char action[8],url[256];
  2388. writeLog(FUN, "SWITCH", "CLOSED");
  2389. GetCmdValue(SPK_CONF, "intercom:closed_action", action, sizeof(action));
  2390. if(strcmp(action,"call") == 0)
  2391. {
  2392. outgoingCall(CLOSED);
  2393. }
  2394. else if(strcmp(action,"hangup") == 0)
  2395. {
  2396. if(BARESIP_STATUS == RINGING || BARESIP_STATUS == INUSE)
  2397. {
  2398. if(DEBUG)
  2399. printf( "hangup call\n" );
  2400. control_cmd(BARESIP_CHAN, "{\"cmd\":\"hangup\",\"data\":\"\"}");
  2401. writeLog( FUN, "CLOSED Hangup", "" );
  2402. }
  2403. }
  2404. else if(strcmp(action,"http") == 0)
  2405. {
  2406. GetCmdValue(SPK_CONF, "intercom:closed_http_url", url, sizeof(url));
  2407. action_url(url);
  2408. writeLog(FUN, "CLOSED HTTP Request", url);
  2409. }
  2410. else if(strcmp(action,"play") == 0)
  2411. {
  2412. char audiofile[32],repeat_tmp[16];
  2413. GetCmdValue(SPK_CONF, "intercom:closed_audio_file", audiofile, sizeof(audiofile));
  2414. GetCmdValue(SPK_CONF, "intercom:closed_audio_repeat", repeat_tmp, sizeof(repeat_tmp));
  2415. int repeat = atoi(repeat_tmp);
  2416. play_audio(audiofile,repeat);
  2417. sprintf(strtmp, "File: %s; Repeat: %d", audiofile, repeat);
  2418. writeLog( FUN, "CLOSED Play Auido", strtmp );
  2419. }
  2420. else if(strcmp(action,"stop") == 0)
  2421. {
  2422. control_cmd(BARESIP_CHAN, "{\"cmd\":\"play\",\"data\":\"\"}");
  2423. writeLog( FUN, "CLOSED Stop Audio", "" );
  2424. }
  2425. if(strcmp(input,"closed") == 0)
  2426. {
  2427. outputControl(GPIO_135, GPIO_ON);
  2428. if(DEBUG)
  2429. printf( "gpio135 set on\n" );
  2430. //gpio触发后判断是否为延时复位
  2431. pthread_t thread_delay;
  2432. pthread_create(&thread_delay, NULL, gpioDelayControl, NULL);
  2433. pthread_detach(thread_delay);
  2434. }
  2435. }
  2436. }
  2437. else
  2438. {
  2439. if(strcmp(type,"switch") == 0)
  2440. {
  2441. char action[8],url[256];
  2442. writeLog(FUN, "SWITCH", "OPEN");
  2443. GetCmdValue(SPK_CONF, "intercom:open_action", action, sizeof(action));
  2444. if(strcmp(action,"call") == 0)
  2445. {
  2446. outgoingCall(OPEN);
  2447. }
  2448. else if(strcmp(action,"hangup") == 0)
  2449. {
  2450. if(BARESIP_STATUS == RINGING || BARESIP_STATUS == INUSE)
  2451. {
  2452. if(DEBUG)
  2453. printf( "hangup call\n" );
  2454. control_cmd(BARESIP_CHAN, "{\"cmd\":\"hangup\",\"data\":\"\"}");
  2455. writeLog( FUN, "OPEN Hangup", "" );
  2456. }
  2457. }
  2458. else if(strcmp(action,"http") == 0)
  2459. {
  2460. GetCmdValue(SPK_CONF, "intercom:open_http_url", url, sizeof(url));
  2461. action_url(url);
  2462. writeLog(FUN, "OPEN HTTP Request", url);
  2463. }
  2464. else if(strcmp(action,"play") == 0)
  2465. {
  2466. char audiofile[32],repeat_tmp[16];
  2467. GetCmdValue(SPK_CONF, "intercom:open_audio_file", audiofile, sizeof(audiofile));
  2468. GetCmdValue(SPK_CONF, "intercom:open_audio_repeat", repeat_tmp, sizeof(repeat_tmp));
  2469. int repeat = atoi(repeat_tmp);
  2470. play_audio(audiofile,repeat);
  2471. sprintf(strtmp, "File: %s; Repeat: %d", audiofile, repeat);
  2472. writeLog( FUN, "OPEN Play Auido", strtmp );
  2473. }
  2474. else if(strcmp(action,"stop") == 0)
  2475. {
  2476. control_cmd(BARESIP_CHAN, "{\"cmd\":\"play\",\"data\":\"\"}");
  2477. writeLog( FUN, "OPEN Stop Audio", "" );
  2478. }
  2479. if(strcmp(input,"open") == 0)
  2480. {
  2481. outputControl(GPIO_135, GPIO_ON);
  2482. if(DEBUG)
  2483. printf( "gpio135 set on\n" );
  2484. //gpio触发后判断是否为延时复位
  2485. pthread_t thread_delay;
  2486. pthread_create(&thread_delay, NULL, gpioDelayControl, NULL);
  2487. pthread_detach(thread_delay);
  2488. }
  2489. }
  2490. }
  2491. }
  2492. /*RESET*/
  2493. if( fdset[1].revents & POLLPRI )
  2494. {
  2495. count = 0;
  2496. for(i=0;i<100;i++){ // 100ms
  2497. bzero(buf,sizeof(buf));
  2498. read(fdset[1].fd, buf, sizeof(buf));
  2499. lseek(fdset[1].fd, 0, SEEK_SET);
  2500. if(buf[0]-'0' == 0)
  2501. count++;
  2502. usleep(1000);
  2503. }
  2504. if (count >= 70) {
  2505. time(&newtime);
  2506. printf("KEY DOWN\n");
  2507. writeLog(BTN, "RESET", "DOWN");
  2508. } else {
  2509. time(&lastime);
  2510. len = lastime - newtime;
  2511. printf("KEY UP, Time:%d\n", len);
  2512. sprintf(strtmp, "Release <Duration %ds>", len);
  2513. writeLog(BTN, "RESET", strtmp);
  2514. if(len > 10)
  2515. {
  2516. keyAction(KEY3);
  2517. }
  2518. else if(len > 3)
  2519. {
  2520. keyAction(KEY4_3)
  2521. }
  2522. }
  2523. }
  2524. }
  2525. }