mail.c 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558
  1. #include <stdint.h>
  2. #include <pthread.h>
  3. #include "cfg.h"
  4. #include "sys.h"
  5. #include "cellular.h"
  6. #include "common.h"
  7. #include "thread.h"
  8. #include "xlist.h"
  9. #include "elog.h"
  10. #include "lock.h"
  11. #include "sqlite_handle.h"
  12. #include <curl/curl.h>
  13. #include "mail.h"
  14. #if 1
  15. #define LOGD log_d
  16. #define LOGE log_e
  17. #define LOGW log_w
  18. #else
  19. #define LOGD printf
  20. #define LOGE printf
  21. #define LOGW printf
  22. #endif
  23. typedef struct {
  24. char sub[128];
  25. char body[2048];
  26. char attach[128];
  27. }mail_pkt_t;
  28. typedef struct {
  29. handle_t list;
  30. mail_info_t *info;
  31. GlobalDeviceManager *dm;
  32. int inited;
  33. }mail_handle_t;
  34. static mail_handle_t maHandle;
  35. static char send_buff[4096];
  36. struct upload_status
  37. {
  38. size_t bytes_read;
  39. };
  40. static size_t payload_source(char *ptr, size_t size, size_t nmemb, void *userp)
  41. {
  42. struct upload_status *upload_ctx = (struct upload_status *)userp;
  43. const char *data;
  44. size_t room = size * nmemb;
  45. if((size == 0) || (nmemb == 0) || ((size*nmemb) < 1)) {
  46. return 0;
  47. }
  48. data = &send_buff[upload_ctx->bytes_read];
  49. if(data) {
  50. size_t len = strlen(data);
  51. if(room < len)
  52. len = room;
  53. memcpy(ptr, data, len);
  54. upload_ctx->bytes_read += len;
  55. return len;
  56. }
  57. return 0;
  58. }
  59. static void fill_send_buff(char *dst_buf, const char *to,const char *from,const char *subject,const char *body)
  60. {
  61. time_t timer;//time_t就是long int 类型
  62. struct tm *tblock;
  63. timer = time(NULL);
  64. tblock = localtime(&timer);
  65. sprintf(dst_buf,"Subject: %s\r\n"
  66. "From: %s\r\n"
  67. "To: %s\r\n"
  68. "Date: %s\r\n"
  69. "\r\n"
  70. "%s\r\n"
  71. "\r\n",subject,from,to,asctime(tblock),body);
  72. }
  73. static int curl_add_files(curl_mime *mm, char *attach)
  74. {
  75. curl_mimepart *part;
  76. int nlen=strlen(attach);
  77. char *p,*tmp=strdup(attach),*p2;
  78. if(!tmp) {
  79. return -1;
  80. }
  81. p = tmp;
  82. p2 = tmp+nlen;
  83. while(*p) {
  84. if((*p)==';') *p=0;
  85. p++;
  86. }
  87. p = tmp;
  88. while(1) {
  89. if(p>=p2) break;
  90. part = curl_mime_addpart(mm);
  91. if(!part) {
  92. printf("____part is null!\n");
  93. free(tmp); return -1;
  94. }
  95. curl_mime_name(part, "file");
  96. curl_mime_filedata(part, p);
  97. p += strlen(p)+1;
  98. }
  99. free(tmp);
  100. return 0;
  101. }
  102. static int send_mail(mail_send_t *send, void *addr, char *sub, char *body, char *attach, int multi)
  103. {
  104. int i=0;
  105. CURLcode r=CURLE_OK;
  106. char tmp[100];
  107. char url_buff[256]={0};
  108. char to_buff[256]={0};
  109. mail_handle_t *h=&maHandle;
  110. struct upload_status upload_ctx = { 0 };
  111. struct curl_slist *recipients = NULL;
  112. mail_recv_t *recv=(mail_recv_t*)addr;
  113. curl_mime *mm=NULL,*alt=NULL;
  114. curl_mimepart *part=NULL;
  115. struct curl_slist *slist=NULL;
  116. struct curl_slist *headers=NULL;
  117. const char **cpp;
  118. lock_s_hold(LOCK_ID_MAIL);
  119. CURL *curl = curl_easy_init();
  120. if(!curl) {
  121. goto out;
  122. }
  123. sprintf(url_buff,"%s:%s",send->server,send->port);
  124. r = curl_easy_setopt(curl,CURLOPT_URL,url_buff);
  125. //curl_easy_setopt(curl, CURLOPT_CUSTOMREQUEST, "EXPN");
  126. //curl_easy_setopt(curl, CURLOPT_MAIL_AUTH, "<secret@cave>");
  127. //curl_easy_setopt(curl, CURLOPT_SASL_AUTHZID, "ursel");
  128. //sprintf(tmp, "AUTH=%s", send->auth);
  129. //curl_easy_setopt(curl, CURLOPT_LOGIN_OPTIONS, tmp);
  130. r = curl_easy_setopt(curl, CURLOPT_USERNAME, send->account); //setting user
  131. r = curl_easy_setopt(curl, CURLOPT_PASSWORD, send->password); //setting password
  132. //if(cellular_is_connected()) {
  133. //r = curl_easy_setopt(curl, CURLOPT_INTERFACE, sys_get_ifname(NIC_USB));
  134. //}
  135. if(strcmp(send->port, "587")==0) { //tls
  136. r = curl_easy_setopt(curl, CURLOPT_USE_SSL, CURLUSESSL_ALL); //setting openssl/tls
  137. //curl_easy_setopt(curl, CURLOPT_CAINFO, "/path/to/certificate.pem");
  138. }
  139. curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0L);
  140. curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 0L);
  141. //curl_easy_setopt(curl, CURLOPT_USERAGENT, CLIENT_USERAGENT);
  142. r = curl_easy_setopt(curl, CURLOPT_MAIL_FROM, send->account);
  143. r = curl_easy_setopt(curl, CURLOPT_READFUNCTION, payload_source);
  144. r = curl_easy_setopt(curl, CURLOPT_READDATA, &upload_ctx);
  145. if(multi) {
  146. for(int i=0; i<MAIL_RECV_MAX; i++) {
  147. if(recv[i].use && strlen(recv[i].account)>0) {
  148. recipients = curl_slist_append(recipients, recv[i].account);
  149. //recipients = curl_slist_append(recipients, CC_MAIL);
  150. strcat(to_buff,recv[i].account);
  151. strcat(to_buff,";");
  152. }
  153. }
  154. }
  155. else {
  156. char *sendto=(char*)addr;
  157. recipients = curl_slist_append(recipients,sendto);
  158. strcat(to_buff,sendto);
  159. strcat(to_buff,";");
  160. }
  161. fill_send_buff(send_buff,to_buff,send->account,sub,body);
  162. if(attach && strlen(attach)>0) {
  163. mm = curl_mime_init(curl);
  164. alt = curl_mime_init(curl);
  165. headers = curl_slist_append(headers, send_buff);
  166. curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers);
  167. part = curl_mime_addpart(alt);
  168. curl_mime_data(part, sub, CURL_ZERO_TERMINATED);
  169. part = curl_mime_addpart(mm);
  170. curl_mime_subparts(part, alt);
  171. curl_mime_type(part, "multipart/alternative");
  172. slist = curl_slist_append(NULL, "Content-Disposition: inline");
  173. curl_mime_headers(part, slist, 1);
  174. //part = curl_mime_addpart(mm);
  175. //curl_mime_name(part, "file");
  176. //curl_mime_filedata(part, attach);
  177. curl_add_files(mm, attach);
  178. curl_easy_setopt(curl, CURLOPT_MIMEPOST, mm);
  179. }
  180. //r = curl_easy_setopt(curl, CURLOPT_CONNECTTIMEOUT, 5L);
  181. //r = curl_easy_setopt(curl, CURLOPT_TIMEOUT, 30L);
  182. r = curl_easy_setopt(curl, CURLOPT_UPLOAD, 1L);
  183. r = curl_easy_setopt(curl, CURLOPT_MAIL_RCPT, recipients);
  184. r = curl_easy_setopt(curl, CURLOPT_VERBOSE, 1L);
  185. r = curl_easy_perform(curl);
  186. if(r != CURLE_OK) {
  187. LOGE("send mail failed, %d, %s\n", r, curl_easy_strerror(r));
  188. }
  189. else {
  190. LOGD("send mail ok!\n");
  191. }
  192. curl_slist_free_all(recipients);
  193. curl_mime_free(mm);
  194. out:
  195. if(curl) curl_easy_cleanup(curl);
  196. lock_s_release(LOCK_ID_MAIL);
  197. return (r==CURLE_OK)?0:-1;
  198. }
  199. ////////////////////////////////////////////////////////////////////////////
  200. static void sleep_ms(int ms)
  201. {
  202. usleep(ms*1000);
  203. }
  204. static void* mail_thread(void *arg)
  205. {
  206. #ifdef USE_MAIL
  207. int r;
  208. thread_handle_t *th=(thread_handle_t*)arg;
  209. mail_handle_t *h=(mail_handle_t*)th->arg;
  210. list_node_t *ln=NULL;
  211. mail_pkt_t *pkt=NULL;
  212. mail_send_t *send=&h->info->send;
  213. mail_recv_t *recv=h->info->recv;
  214. while(th->quit==0) {
  215. r = xlist_take_node(h->list, &ln, 0);
  216. if(r==0) {
  217. pkt = (mail_pkt_t*)ln->data.buf;
  218. send_mail(send, recv, pkt->sub, pkt->body, pkt->attach, 1);
  219. xlist_back_node(h->list, ln);
  220. }
  221. sleep_ms(100);
  222. }
  223. #endif
  224. pthread_exit(NULL);
  225. }
  226. int mail_init(void)
  227. {
  228. #ifdef USE_MAIL
  229. list_cfg_t lc;
  230. mail_handle_t *h=&maHandle;
  231. GlobalDeviceManager *dm=&__globalDeviceManage;
  232. lc.mode = LIST_FULL_FIFO;
  233. lc.max = 100;
  234. lc.log = 0;
  235. h->list = xlist_init(&lc);
  236. h->dm = dm;
  237. h->info = &h->dm->mailInfo;
  238. dev_mail_init(dm->db, h->info);
  239. thread_start(THREAD_ID_MAIL, mail_thread, h);
  240. h->inited = 1;
  241. //mail_test();
  242. #endif
  243. return 0;
  244. }
  245. int mail_deinit(void)
  246. {
  247. #ifdef USE_MAIL
  248. mail_handle_t *h=&maHandle;
  249. thread_stop(THREAD_ID_MAIL);
  250. xlist_free(h->list);
  251. h->inited = 0;
  252. #endif
  253. return 0;
  254. }
  255. static int post_data(char *sub, char *body, char *attach)
  256. {
  257. int r=0;
  258. #ifdef USE_MAIL
  259. mail_pkt_t pkt;
  260. mail_handle_t *h=&maHandle;
  261. snprintf(pkt.sub, sizeof(pkt.sub), "%s", sub?sub:"");
  262. snprintf(pkt.body, sizeof(pkt.body), "%s", body?body:"");
  263. snprintf(pkt.attach, sizeof(pkt.attach), "%s", attach?attach:"");
  264. r = xlist_append(h->list, 0, &pkt, sizeof(pkt));
  265. #endif
  266. return r;
  267. }
  268. int mail_send(char *sub, char *body, char *attach)
  269. {
  270. int r=-1;
  271. #ifdef USE_MAIL
  272. mail_handle_t *h=&maHandle;
  273. if(!h->inited || !h->info || !h->info->send.mode) {
  274. return -1;
  275. }
  276. r = send_mail(&h->info->send, h->info->recv, sub?sub:"", body?body:"", attach?attach:"", 1);
  277. #endif
  278. return r;
  279. }
  280. int mail_post(char *sub, char *body, char *attach)
  281. {
  282. int r=-1;
  283. #ifdef USE_MAIL
  284. mail_handle_t *h=&maHandle;
  285. if(!h->inited || !h->info || !h->info->send.mode) {
  286. return -1;
  287. }
  288. r = post_data(sub, body, attach);
  289. #endif
  290. return r;
  291. }
  292. int mail_post_alarm(int type, int subtype, int alarm_type, char *content)
  293. {
  294. int r=0;
  295. #ifdef USE_MAIL
  296. mail_pkt_t pkt;
  297. char temp[128];
  298. mail_handle_t *h=&maHandle;
  299. if(!h->inited || !content || !h->info || !h->info->send.mode) {
  300. return -1;
  301. }
  302. char *prod_name=h->dm->_globalDevInfo.product.name;
  303. int prod_id=h->dm->_globalDevInfo.product.id;
  304. int langID=h->dm->_globalDevInfo.product.language;
  305. switch(type) {
  306. case ALARM_TYPE_POWER:
  307. {
  308. if(subtype) {
  309. switch(alarm_type) {
  310. case ENABLE_TAC_V_UP:
  311. case ENABLE_TAC_V_DOWN:
  312. snprintf(temp, sizeof(temp), "%s %d %s %s %s", prod_name, prod_id, language_alarm_V[langID], language_exceed[langID], language_alarm[langID]);
  313. break;
  314. case ENABLE_TAC_A_UP:
  315. snprintf(temp, sizeof(temp), "%s %d %s %s %s", prod_name, prod_id, language_alarm_A[langID], language_exceed[langID], language_alarm[langID]);
  316. break;
  317. case ENABLE_TAC_W_UP:
  318. snprintf(temp, sizeof(temp), "%s %d %s %s %s", prod_name, prod_id, language_alarm_W[langID], language_exceed[langID], language_alarm[langID]);
  319. break;
  320. case ENABLE_TAC_P_UP:
  321. snprintf(temp, sizeof(temp), "%s %d %s %s %s", prod_name, prod_id, language_alarm_P[langID], language_exceed[langID], language_alarm[langID]);
  322. break;
  323. case ENABLE_TAC_STIME:
  324. case ENABLE_TAC_ETIME:
  325. snprintf(temp, sizeof(temp), "%s %d %s %s", prod_name, prod_id, language_alarm_phase_lose[langID], language_alarm[langID]);
  326. break;
  327. default:
  328. return -1;
  329. }
  330. }
  331. else {
  332. switch(alarm_type) {
  333. case WARNING_V_UP:
  334. case WARNING_V_DOWN:
  335. snprintf(temp, sizeof(temp), "%s %d %s %s %s", prod_name, prod_id, language_alarm_V[langID], language_exceed[langID], language_alarm[langID]);
  336. break;
  337. case WARNING_A_UP:
  338. snprintf(temp, sizeof(temp), "%s %d %s %s %s", prod_name, prod_id, language_alarm_A[langID], language_exceed[langID], language_alarm[langID]);
  339. break;
  340. case WARNING_W_UP:
  341. snprintf(temp, sizeof(temp), "%s %d %s %s %s", prod_name, prod_id, language_alarm_W[langID], language_exceed[langID], language_alarm[langID]);
  342. break;
  343. case WARNING_P_UP:
  344. snprintf(temp, sizeof(temp), "%s %d %s %s %s", prod_name, prod_id, language_alarm_P[langID], language_exceed[langID], language_alarm[langID]);
  345. break;
  346. case 0 ... 2:
  347. snprintf(temp, sizeof(temp), "%s %d %s %s", prod_name, prod_id, language_alarm_phase_lose[langID], language_alarm[langID]);
  348. break;
  349. default:
  350. return -1;
  351. }
  352. }
  353. }
  354. break;
  355. case ALARM_TYPE_SENSOR:
  356. {
  357. switch(subtype) {
  358. case SENSOR_TYPE_TEMP_DOUBLE:
  359. case SENSOR_TYPE_TEMP_HUMI:
  360. case SENSOR_TYPE_TEMP:
  361. snprintf(temp, sizeof(temp), "%s %d %s %s", prod_name, prod_id, language_temperature[langID], language_alarm[langID]);
  362. break;
  363. case SENSOR_TYPE_SMOKE:
  364. snprintf(temp, sizeof(temp), "%s %d %s %s", prod_name, prod_id, language_sensor_smoke[langID], language_alarm[langID]);
  365. break;
  366. case SENSOR_TYPE_WATER:
  367. snprintf(temp, sizeof(temp), "%s %d %s %s", prod_name, prod_id, language_humidity[langID], language_alarm[langID]);
  368. break;
  369. case SENSOR_TYPE_ACCESS:
  370. snprintf(temp, sizeof(temp), "%s %d %s %s", prod_name, prod_id, language_sensor_access[langID], language_alarm[langID]);
  371. break;
  372. case SENSOR_TYPE_GAS:
  373. snprintf(temp, sizeof(temp), "%s %d %s %s", prod_name, prod_id, language_atmosphere_gas[langID], language_alarm[langID]);
  374. break;
  375. case SENSOR_TYPE_AIR_PRESS:
  376. snprintf(temp, sizeof(temp), "%s %d %s %s", prod_name, prod_id, language_atmosphere_pressure[langID], language_alarm[langID]);
  377. break;
  378. case SENSOR_TYPE_LEAK:
  379. snprintf(temp, sizeof(temp), "%s %d %s %s", prod_name, prod_id, language_sensor_leak[langID], language_alarm[langID]);
  380. break;
  381. default:
  382. return -1;
  383. }
  384. }
  385. break;
  386. case ALARM_TYPE_NETWORK:
  387. {
  388. snprintf(temp, sizeof(temp), "%s %d %s", prod_name, prod_id, language_alarm_Type_Network[langID]);
  389. }
  390. break;
  391. default:
  392. return -1;
  393. }
  394. replace_sequences(content, h->dm->alarmTab);
  395. r = post_data(temp, content, NULL);
  396. #endif
  397. return r;
  398. }
  399. int mail_test(void)
  400. {
  401. int r=0,cnt=0;
  402. #ifdef USE_MAIL
  403. char temp[200];
  404. mail_handle_t *h=&maHandle;
  405. mail_info_t info={
  406. .send = {
  407. .id = 0,
  408. .mode = 1,
  409. #if 0
  410. .account = "rcp064867@163.com",
  411. .password = "YWKVURARCJXYXQVS",
  412. .server = "smtp.163.com",
  413. .port = "25",
  414. //.port = "465",
  415. //.port = "587",
  416. .auth = "PLAIN",
  417. //.auth = "LOGIN",
  418. //.auth = "CRAM-MD5",
  419. #else
  420. .account = "jiuci4902@gmail.com",
  421. .password = "wmfoedxaycdwllvs",
  422. .server = "smtp.gmail.com",
  423. //.port = "25",
  424. //.port = "465",
  425. .port = "587",
  426. //.auth = "PLAIN",
  427. .auth = "LOGIN",
  428. //.auth = "CRAM-MD5",
  429. #endif
  430. },
  431. .recv = {
  432. {0, 1, "1556907721@qq.com"},
  433. {1, 1, "rcp064867@163.com"},
  434. {2, 1, "cijiu0219@sina.com"},
  435. {3, 1, "jiuci4902@gmail.com"},
  436. {4, 1, "cijiu0219@hotmail.com"},
  437. {5, 1, "cijiu990219@outlook.com"},
  438. {6, 1, "iauther@163.com"},
  439. }
  440. };
  441. *h->info = info;
  442. char *sub="123";
  443. char *body="hello everyone";
  444. while(cnt++<5) {
  445. sprintf(temp, "%s %d", body, cnt);
  446. r = mail_send(sub, temp, NULL);
  447. sleep(2);
  448. }
  449. #endif
  450. return r;
  451. }