📄 s35_sms.c
字号:
/*************************************************************************** * copyright : (C) 2002 by Hendrik Sattler * * mail : post@hendrik-sattler.de * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/#include "common.h"#include "helpers.h"#include <errno.h>#include <string.h>#include <stdlib.h>void sms_s35(int action, char* file, char* pipe, struct parameters myparams, struct smsopts mysmsopts){ char at_command[128]; char* ausgabe; char* storetype; char* pdu; int min,max; memset(at_command,0,sizeof(at_command)); if (strlen(myparams.mem)) { storetype=str_dup(myparams.mem); } else { ausgabe=get_smsmemtypes(); if (ausgabe==NULL) { return; } else if (strstr(ausgabe,"\"MT\"")!=NULL) { storetype=str_dup("MT"); } else { storetype=str_dup("SM"); } mem_realloc(ausgabe,0); } new_at_command(at_command,"+CPMS="); add_at_command(at_command,"%s,%s",storetype,storetype); ausgabe=tty_write_read(at_command); if (strncmp(ausgabe,"+CPMS: ",7)) { errexit("SMS storage type \"%s\" could not be selected.\n",storetype); } mem_realloc(storetype,0); mem_realloc(tty_read(at_command),0); max=atoi(index(ausgabe,',')+1); min=1; mem_realloc(ausgabe,0); switch(action){ case 0: case 1: errexit("You must specify an operation.\n"); break; case 2: //deleting if (myparams.slot<=0) { get_sms_s35(file, pipe, myparams, action); } else { delete_sms_s35(myparams.slot); } break; case 4: //sending from/to SMS memory if (myparams.slot) { if (strlen(myparams.number)) { send_smsslot_s35(myparams.slot,myparams.number); } else { get_sms_s35(file, pipe, myparams, action); } } else { pdu=create_smspdu(file,myparams.text,myparams.number,mysmsopts); send_smspdu(pdu,0); } break; case 5: //sending through the phone pdu=create_smspdu(file,myparams.text,myparams.number,mysmsopts); send_smspdu(pdu,1); break; case 9: //getting messages as unexpected notice from the phone get_direct_sms_s35(file,pipe); break; default: //get-and-delete-and-send messages get_sms_s35(file, pipe, myparams, action); break; } memset(myparams.text,0,strlen(myparams.text)); //so we do not submit the same sms multiple times}void delete_sms_s35(int smsslot){ char at_command[128]; char* ack; memset(at_command,0,sizeof(at_command)); if (smsslot>0) { new_at_command(at_command,"+CMGD"); add_at_command(at_command,"=%d",smsslot); ack=tty_write_read(at_command); if (!strcmp(ack,"OK")) { myprintf(0,"SMS slot %d was deleted.\n",smsslot); } else if(!strcmp(ack,"+CMS ERROR: INVALID MEMORY INDEX")) { errexit("This index is not available.\n"); } else if(strstr(ack,"ERROR")!=NULL) { errexit("%s, aborting.\n",ack); } mem_realloc(ack,0); } else { errexit("You must specify a valid slot number.\n"); }}void send_smsslot_s35(int smsslot, char* smsnumber){ char at_command[128]; char* ausgabe; char buffer; memset(at_command,0,sizeof(at_command)); new_at_command(at_command,"+CMSS"); add_at_command(at_command,"=%d",smsslot); if (strlen(smsnumber)>0) { add_at_command(at_command,",%s",smsnumber); buffer=smsnumber[0]; if (buffer=='+') { add_at_command(at_command,",145"); } else { add_at_command(at_command,",129"); } } ausgabe=tty_write_read(at_command); if (!strcmp(ausgabe,"+CMS ERROR: INVALID MEMORY INDEX")) { errexit("This index is not available.\n"); } else if(strstr(ausgabe,"ERROR")!=NULL) { errexit("%s, aborting.\n",ausgabe); } myprintf(0,"The message was sent. Message referrer: %s\n",ausgabe+7); mem_realloc(ausgabe,0); ausgabe=tty_read(at_command); myprintf(0,"The phone returned: %s\n",ausgabe); mem_realloc(ausgabe,0);}char* create_smspdu (char* file, char* smstext, char* smsnumber, struct smsopts mysmsopts) { static char pdu[BUFSIZ]; char smsinput[161]; int myfd,i,eof_present=0,read_ret; memset(pdu,0,sizeof(pdu)); memset(smsinput,0,sizeof(smsinput)); if (strlen(smstext)==0) {// --sms-text was not used, look for other sources myfd=open_myFile_ro(file); for (i=0;i<sizeof(smsinput)-1;i++) { read_ret=read(myfd,&smsinput[i],1); if (read_ret==0) { eof_present=1; break; } else if (read_ret==-1) { errexit("Error while reading from file.\n"); } } if (eof_present==0) { errexit("SMS text is too long (max. %d characters).\n",sizeof(smsinput)-1); } if (strlen(smsinput)==0) { errexit("No SMS text found (or zero length).\n"); } else { myprintf(0,"%s has %d bytes.\n",file,strlen(smsinput)); } } else { if (strlen(smstext)>=sizeof(smsinput)) { errexit("SMS text is too long (max. %d characters).\n",sizeof(smsinput)-1); } else { strcpy(smsinput,smstext); } } myprintf(0,"Creating PDU...\n"); create_smssubmit_pdu(pdu,smsinput,smsnumber,mysmsopts); myprintf(1,"PDU: %s\n",pdu); return pdu;}void send_smspdu (char* pdu, int direct) { char at_command[128]; char* ausgabe; char* ack; char temp[3]; memset(at_command,0,sizeof(at_command)); if (direct) { new_at_command(at_command,"+CMGS"); } else { new_at_command(at_command,"+CMGW"); } strncpy(temp,pdu,2); temp[3]=0; add_at_command(at_command,"=%d",(strlen(pdu)/2)-atoi(temp)-1); tty_write_command(at_command); myprintf(0,"Waiting for data request...\n"); //tty_read_limited(at_command,ack,2); ack=tty_read(at_command); if (!strncmp(ack,"> ",2)) { mem_realloc(ack,0); myprintf(0,"Sending data...\n"); if (tty_write_data(pdu,strlen(pdu)) == -1) { errexit("ERROR on sending data: %s\n", strerror(errno)); } ausgabe=tty_read(at_command); if (strstr(ausgabe,"ERROR")!=NULL) { errexit("An error occured on sending the SMS: %s\n",ausgabe); } if (direct) { myprintf(0,"The message was sent. Message referrer: %s\n",ausgabe+7); } else { myprintf(0,"The message was saved to SMS memory slot %s\n",ausgabe+7); } mem_realloc(ausgabe,0); ack=tty_read(at_command); myprintf(0,"The phone returned: %s\n",ack); mem_realloc(ack,0); } else { //tty_read_limited(at_command,&ack[2],sizeof(ack)-3); if (!strncmp(ack,"ERROR",5)) { errexit("An unknown error occured."); } else if (!strcasecmp(ack,"+CMS ERROR: MEMORY FULL")) { errexit("There is no slot free to store the sms.\n"); } else { errexit("ERROR: %s\n",ack+12); } mem_realloc(ack,0); }}void get_sms_s35(char* file, char* pipe, struct parameters myparams, int action){ char at_command[128]; char* ausgabe; char* ack; int myfd=-1; FILE *pipefd = NULL; struct input { sms_data_t sms; int status; struct input* next; struct input* prev; } array; typedef struct input input_t; input_t* current; current=&array; memset(at_command,0,sizeof(at_command)); if (myparams.slot>0) { new_at_command(at_command,"+CMGR"); add_at_command(at_command,"=%d",myparams.slot); } else { // 0=unread, -1=read, -2=unsent, -3=sent, -4=all if (myparams.slot<(-4)) { myparams.slot=0; } new_at_command(at_command,"+CMGL"); add_at_command(at_command,"=%d",myparams.slot*(-1)); } if (!strlen(file) && !strlen(pipe) && myparams.slot==0) { errexit("This changes the status of the requested sms from \"unread\" to \"read\" but no output method was specified.\n"); } ausgabe=tty_write_read(at_command); if (!strcmp(ausgabe,"OK")) { errexit("There are no SMS of this type on the phone.\n"); } else if (!strcmp(ausgabe,"+CMS ERROR: INVALID MEMORY INDEX")) { errexit("This index is not available.\n"); } else if (strstr(ausgabe,"ERROR")!=NULL) { errexit("%s, aborting.\n",ausgabe); } else { if (strlen(file)) { myfd=open_myFile_rw(file); } myprintf(0,"Looking for SMS of specified type...\n"); while (strcmp(ausgabe,"OK") && strcmp(ausgabe,"ERROR")) { if (myparams.slot>0) { current->sms.slot=myparams.slot; current->status=atoi((char *)strtok(&ausgabe[7],",")); } else { current->sms.slot=atoi((char *)strtok(&ausgabe[7],",")); current->status=atoi((char *)strtok(NULL,",")); } switch (current->status) { case 0: case 1: current->sms.type=0; break; case 2: case 3: current->sms.type=1; break; default: current->sms.type=-1; break; } if ((action>>3)&1) { myprintf(0,"Receiving "); switch (current->status) { case 0: myprintf(0,"incoming, unread SMS "); break; case 1: myprintf(0,"incoming, read SMS "); break; case 2: myprintf(0,"outgoing, unsent SMS "); break; case 3: myprintf(0,"outgoing, sent SMS "); break; default: myprintf(0,"SMS of unknown type "); break; } myprintf(0,"from slot %d.\n",current->sms.slot); } //the value of the last parameter gives the length of the real PDU in Octets //but we keep the whole tpdu and should not trust that value anyway mem_realloc(ausgabe,0); ausgabe=tty_read(at_command); if (!strcmp(ausgabe,"OK")) { close(myfd); errexit("Slot %d is empty.\n", current->sms.slot); } else { if (strlen(ausgabe)<sizeof(current->sms.tpdu)) { memset(current->sms.tpdu,0,sizeof(current->sms.tpdu)); strncpy(current->sms.tpdu,ausgabe,strlen(ausgabe)); } else { errexit("Buffer-Overflow in TPDU variable.\n"); } mem_realloc(ausgabe,0); ausgabe=tty_read(at_command); if (strcmp(ausgabe,"OK") && strcmp(ausgabe,"ERROR")) { current->next=mem_alloc(sizeof(input_t),0); current->next->prev=current; current=current->next; } else { current->prev=NULL; } current->next=NULL; } } mem_realloc(ausgabe,0); current=&array; do { if ((action>>3)&1) { ack=mem_alloc(BUFSIZ,0); sprintf(ack,"Slot: %d\n",current->sms.slot); //decode PDU ausgabe=mem_alloc(BUFSIZ,1); strcpy(ausgabe,current->sms.tpdu); decode_smsdeliver_pdu(ausgabe, current->status); //now save it if (myfd!=-1) { if (write(myfd,ack,strlen(ack)) == -1 || write(myfd,ausgabe,strlen(ausgabe)) == -1 || write(myfd,"\n",1) == -1) { close(myfd); errexit("\nERROR on writing to %s: %s\n",file, strerror(errno)); } } if (strlen(pipe)) { //also send output (splitted) to a given pipe pipefd=popen(pipe,"w"); if (pipefd!=NULL) { if (fwrite(ausgabe,1,strlen(ausgabe),pipefd)!=strlen(ausgabe)){ close(myfd); pclose(pipefd); errexit("\nERROR on writing to pipe \"%s\".\n",pipe); } if (pclose(pipefd)==-1) { close(myfd); errexit("\nERROR on closing pipe \"%s\".\n",pipe); } } } mem_realloc(ausgabe,0); mem_realloc(ack,0); } if ((action>>2)&1) { myprintf(0,"Trying to send SMS from slot %d...\n",current->sms.slot); if (current->sms.type==1) { if (strlen(myparams.number)) { send_smsslot_s35(current->sms.slot,myparams.number); } else { send_smspdu(current->sms.tpdu,1); } } else { myprintf(0,"Sending like this is only supported with SMS of outgoing type.\n"); } } if ((action>>1)&1) { delete_sms_s35(current->sms.slot); } if (current->next!=NULL) { current=current->next; } else { current=NULL; } } while (current!=NULL); current=&array; while (current->next!=NULL) { current=current->next; } while (current->prev!=NULL) { current=current->prev; if (current->next!=NULL) { mem_realloc(current->next,0); } } close_myFile(myfd); }}void get_direct_sms_s35(char* file, char* pipe){ char at_command[128]; char* ausgabe; char* temp; int myfd=-1; FILE *pipefd = NULL; memset(at_command,0,sizeof(at_command)); if (!strlen(file) && !strlen(pipe)) { errexit("No output method was specified.\n"); } new_at_command(at_command,"+CSMS=1"); ausgabe=tty_write_read(at_command); if (strstr(ausgabe,"ERROR")==NULL) { mem_realloc(tty_read(at_command),0); } else { errexit("Could not set Phase 2+ compatible mode.\n"); } mem_realloc(ausgabe,0); new_at_command(at_command,"+CNMI=1,2,0,0,1"); ausgabe=tty_write_read(at_command); if (strcmp(ausgabe,"OK")) { errexit("Could not set direct mode.\n"); } if (strlen(file)) { myfd=open_myFile_rw(file); } while (1) { do { mem_realloc(ausgabe,0); ausgabe=tty_readline(); if (ausgabe==NULL) { errexit("Error on reading from device: %s\n", strerror(errno)); } if ((temp=index(ausgabe,'\r')) || (temp=index(ausgabe,'\n'))) { memset(temp,0,1); } } while (strlen(ausgabe)==0); if (strncmp(ausgabe,"+CMT: ,",7)) { ausgabe=tty_read(""); ausgabe=mem_realloc(ausgabe,BUFSIZ); decode_smsdeliver_pdu(ausgabe,0); if (myfd!=-1) { if ((write(myfd,ausgabe,strlen(ausgabe)) == -1) ||(write(myfd,"\n",1) == -1)) { close(myfd); errexit("\nERROR on writing to %s: %s\n",file, strerror(errno)); } } else if (strlen(pipe)) { //also send output (splitted) to a given pipe pipefd=popen(pipe,"w"); if (pipefd!=NULL) { if (fwrite(ausgabe,1,strlen(ausgabe),pipefd)!=strlen(ausgabe)){ close(myfd); pclose(pipefd); errexit("\nERROR on writing to pipe \"%s\".\n",pipe); } if (pclose(pipefd)==-1) { close(myfd); errexit("\nERROR on closing pipe \"%s\".\n",pipe); } } } //if this is not sent, SMSC will resent the SMS so we would receive it multiple times mem_realloc(ausgabe,0); ausgabe=tty_write_read("AT+CNMA=0"); if (strcmp(ausgabe,"OK")) { errexit("SMS ACK should have been ok but was not.\n"); } } }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -