📄 sms_funcs.c
字号:
} nr_chunks++; }while (len<text->len); return nr_chunks;}int send_as_sms(struct sms_msg *sms_messg, struct modem *mdm){ static char buf[MAX_SMS_LENGTH]; unsigned int buf_len; unsigned char len_array_1[256], len_array_2[256], *len_array; unsigned int nr_chunks_1, nr_chunks_2, nr_chunks; unsigned int use_nice; str text; char *p, *q; int ret_code; int i; text.s = sms_messg->text.s; text.len = sms_messg->text.len; nr_chunks_1 = split_text( &text, len_array_1, 0); nr_chunks_2 = split_text( &text, len_array_2, 1); if (nr_chunks_1==nr_chunks_2) { len_array = len_array_2; nr_chunks = nr_chunks_2; use_nice = 1; } else { len_array = len_array_1; nr_chunks = nr_chunks_1; use_nice = 0; } sms_messg->ref = 1; for(i=0,p=text.s ; i<nr_chunks&&i<max_sms_parts ; p+=len_array[i++]) { if (use_nice) { q = buf; if (nr_chunks>1 && i) { append_str(q,SMS_EDGE_PART,SMS_EDGE_PART_LEN); *(q-2)=nr_chunks+'0'; *(q-4)=i+1+'0'; } append_str(q,p,len_array[i]); if (nr_chunks>1 && !i) { append_str(q,SMS_EDGE_PART,SMS_EDGE_PART_LEN); *(q-2)=nr_chunks+'0'; *(q-4)=i+1+'0'; } buf_len = q-buf; } else { q = buf; append_str(q,p,len_array[i]); buf_len = len_array[i]; } if (i+1==max_sms_parts && i+1<nr_chunks) { /* simply override the end of the last allowed part */ buf_len += SMS_TRUNCATED_LEN+SMS_FOOTER_LEN; if (buf_len>MAX_SMS_LENGTH) buf_len = MAX_SMS_LENGTH; q = buf + (buf_len-SMS_TRUNCATED_LEN-SMS_FOOTER_LEN); append_str(q,SMS_TRUNCATED,SMS_TRUNCATED_LEN); append_str(q,SMS_FOOTER,SMS_FOOTER_LEN); p += buf_len-SMS_TRUNCATED_LEN-SMS_FOOTER_LEN-SMS_EDGE_PART_LEN; send_error(sms_messg, ERR_TRUNCATE_TEXT, ERR_TRUNCATE_TEXT_LEN, p, text.len-(p-text.s)-SMS_FOOTER_LEN); } DBG("---%d--<%d><%d>--\n|%.*s|\n", i, len_array[i], buf_len, (int)buf_len, buf); sms_messg->text.s = buf; sms_messg->text.len = buf_len; if ( (ret_code=putsms(sms_messg,mdm))<0) goto error; if (sms_report_type!=NO_REPORT) add_sms_into_report_queue(ret_code,sms_messg, p-use_nice*(nr_chunks>1)*SMS_EDGE_PART_LEN,len_array[i]); } sms_messg->ref--; /* put back the pointer to the beginning of the message*/ sms_messg->text.s = text.s; sms_messg->text.len = text.len; /* remove the sms if nobody points to it */ if (!sms_messg->ref){ shm_free(sms_messg); } return 1;error: if (ret_code==-1) /* bad number */ send_error(sms_messg, sms_messg->to.s, sms_messg->to.len, ERR_NUMBER_TEXT, ERR_NUMBER_TEXT_LEN); else if (ret_code==-2) /* bad modem */ send_error(sms_messg, ERR_MODEM_TEXT, ERR_MODEM_TEXT_LEN, text.s+SMS_HDR_BF_ADDR_LEN+sms_messg->from.len+SMS_HDR_AF_ADDR_LEN, text.len-SMS_FOOTER_LEN-SMS_HDR_BF_ADDR_LEN-sms_messg->from.len- SMS_HDR_AF_ADDR_LEN ); if (!(--(sms_messg->ref))) shm_free(sms_messg); return -1;}int send_sms_as_sip( struct incame_sms *sms ){ str sip_addr; str sip_body; str sip_from; int is_pattern; int in_address; int k; char *p; /* first we have to parse the body to try to get out the sip destination address; The sms body can to be in the following two formats: 1. The entire or part of the sent header still exists - we will pars it and consider the start of the sip message the first character that doesn't match the header! 2. The sms body is totally different of the send sms -> search for a sip address inside; everything before it is ignored, only the part following the address being send as sip */ in_address = 0; sip_addr.len = 0; sip_body.len = 0; p = sms->ascii; /* is our logo (or a part of it) still there? */ if (*p==SMS_HDR_BF_ADDR[0]) { is_pattern = 1; /* try to match SMS_HDR_BF_ADDR */ k=0; while( is_pattern && p<sms->ascii+sms->userdatalength && k<SMS_HDR_BF_ADDR_LEN) if (*(p++)!=SMS_HDR_BF_ADDR[k++]) is_pattern = 0; if (!is_pattern) { /* first header part is broken -> let's give it a chance and parse for the first word delimiter */ while(p<sms->ascii+sms->userdatalength && no_sip_addr_begin(*p)) p++; p++; if (p+9>=sms->ascii+sms->userdatalength) { LOG(L_ERR,"ERROR:send_sms_as_sip: unable to find sip_address" " start in sms body [%s]!\n",sms->ascii); goto error; } } /* lets get the address */ if (p[0]!='s' || p[1]!='i' || p[2]!='p' || p[3]!=':') { LOG(L_ERR,"ERROR:send_sms_as_sip: wrong sip address format in" " sms body [%s]!\n",sms->ascii); goto error; } sip_addr.s = p; /* goes to the end of the address */ while(p<sms->ascii+sms->userdatalength && is_in_sip_addr(*p) ) p++; if (p>=sms->ascii+sms->userdatalength) { LOG(L_ERR,"ERROR:send_sms_as_sip: cannot find sip address end in" "sms body [%s]!\n",sms->ascii); } sip_addr.len = p-sip_addr.s; DBG("DEBUG:send_sms_as_sip: sip address found [%.*s]\n", sip_addr.len,sip_addr.s); /* try to match SMS_HDR_AF_ADDR */ k=0; while( is_pattern && p<sms->ascii+sms->userdatalength && k<SMS_HDR_AF_ADDR_LEN) if (*(p++)!=SMS_HDR_AF_ADDR[k++]) is_pattern = 0; } else { /* no trace of the pattern sent along with the orig sms*/ do { if ((p[0]=='s'||p[0]=='S') && (p[1]=='i'||p[1]=='I') && (p[2]=='p'||p[2]=='P') && p[3]==':') { /* we got the address beginning */ sip_addr.s = p; /* goes to the end of the address */ while(p<sms->ascii+sms->userdatalength && is_in_sip_addr(*p) ) p++; if (p==sms->ascii+sms->userdatalength) { LOG(L_ERR,"ERROR:send_sms_as_sip: cannot find sip" " address end in sms body [%s]!\n",sms->ascii); goto error; } sip_addr.len = p-sip_addr.s; } else { /* parse to the next word */ /*DBG("*** Skipping word len=%d\n",sms->userdatalength);*/ while(p<sms->ascii+sms->userdatalength&&no_sip_addr_begin(*p)){ p++; } p++; if (p+9>=sms->ascii+sms->userdatalength) { LOG(L_ERR,"ERROR:send_sms_as_sip: unable to find sip " "address start in sms body [%s]!\n",sms->ascii); goto error; } /*DBG("*** Done\n");*/ } }while (!sip_addr.len); } /* the rest of the sms (if any ;-)) is the body! */ sip_body.s = p; sip_body.len = sms->ascii + sms->userdatalength - p; /* let's trim out all \n an \r from begining */ while ( sip_body.len && sip_body.s && (sip_body.s[0]=='\n' || sip_body.s[0]=='\r') ) { sip_body.s++; sip_body.len--; } if (sip_body.len==0) { LOG(L_WARN,"WARNING:send_sms_as_sip: empty body for sms [%s]", sms->ascii); goto error; } DBG("DEBUG:send_sms_as_sip: extracted body is: [%.*s]\n", sip_body.len, sip_body.s); /* finally, let's send it as sip message */ sip_from.s = sms->sender; sip_from.len = strlen(sms->sender); /* patch the body with date and time */ if (sms->userdatalength + CRLF_LEN + 1 /*'('*/ + DATE_LEN + 1 /*','*/ + TIME_LEN + 1 /*')'*/< sizeof(sms->ascii)) { p = sip_body.s + sip_body.len; append_str( p, CRLF, CRLF_LEN); *(p++) = '('; append_str( p, sms->date, DATE_LEN); *(p++) = ','; append_str( p, sms->time, TIME_LEN); *(p++) = ')'; sip_body.len += CRLF_LEN + DATE_LEN + TIME_LEN + 3; } send_sip_msg_request( &sip_addr, &sip_from, &sip_body); return 1;error: return -1;}int check_sms_report( struct incame_sms *sms ){ struct sms_msg *sms_messg; str *s1, *s2; int old; int res; DBG("DEBUG:sms:check_sms_report: Report for sms number %d.\n",sms->sms_id); res=relay_report_to_queue( sms->sms_id, sms->sender, sms->ascii[0], &old); if (res==3) { /* error */ /* the sms was confirmed with an error code -> we have to send a message to the SIP user */ s1 = get_error_str(sms->ascii[0]); s2 = get_text_from_report_queue(sms->sms_id); sms_messg = get_sms_from_report_queue(sms->sms_id); send_error( sms_messg, s1->s, s1->len, s2->s, s2->len); } else if (res==1 && sms->ascii[0]==48 && old!=48) { /* provisional 48 */ /* the sms was provisional confirmed with a 48 code -> was stored by SMSC -> no further real-time tracing possible */ s2 = get_text_from_report_queue(sms->sms_id); sms_messg = get_sms_from_report_queue(sms->sms_id); send_error( sms_messg, STORED_NOTE, STORED_NOTE_LEN, s2->s, s2->len); } else if (res==2 && old==48) { /* we received OK for a SMS that had received prev. an 48 code. The note that we send for 48 has to be now clarify */ s2 = get_text_from_report_queue(sms->sms_id); sms_messg = get_sms_from_report_queue(sms->sms_id); send_error( sms_messg, OK_MSG, OK_MSG_LEN, s2->s, s2->len); } if (res>1) /* final response */ remove_sms_from_report_queue(sms->sms_id); return 1;}int check_cds_report( struct modem *mdm, char *cds, int cds_len){ struct incame_sms sms; if (cds2sms( &sms, mdm, cds, cds_len)==-1) return -1; check_sms_report( &sms ); return 1;}void modem_process(struct modem *mdm){ struct sms_msg *sms_messg; struct incame_sms sms; struct network *net; int i,k,len; int counter; int dont_wait; int empty_pipe; int cpms_unsuported; int max_mem=0, used_mem=0; sms_messg = 0; cpms_unsuported = 0; /* let's open/init the modem */ DBG("DEBUG:modem_process: opening modem\n"); if (openmodem(mdm)==-1) { LOG(L_ERR,"ERROR:modem_process: cannot open modem %s!" " %s \n",mdm->name,strerror(errno)); return; } setmodemparams(mdm); initmodem(mdm,check_cds_report); if ( (max_mem=check_memory(mdm,MAX_MEM))==-1 ) { LOG(L_WARN,"WARNING:modem_process: CPMS command unsuported!" " using default values (10,10)\n"); used_mem = max_mem = 10; cpms_unsuported = 1; } DBG("DEBUG:modem_process: modem maximum memory is %d\n",max_mem); set_gettime_function(); while(1) { dont_wait = 0; for (i=0;i<nr_of_networks && mdm->net_list[i]!=-1;i++) { counter = 0; empty_pipe = 0; net = &(networks[mdm->net_list[i]]); /*getting msgs from pipe*/ while( counter<net->max_sms_per_call && !empty_pipe ) { /* let's read a sms from pipe */ len = read(net->pipe_out, &sms_messg, sizeof(sms_messg)); if (len!=sizeof(sms_messg)) { if (len>=0) LOG(L_ERR,"ERROR:modem_process: truncated message" " read from pipe! -> discarded\n"); else if (errno==EAGAIN) empty_pipe = 1; else LOG(L_ERR,"ERROR:modem_process: pipe reading failed: " " : %s\n",strerror(errno)); sleep(1); counter++; continue; } (*queued_msgs)--; /* compute and send the sms */ DBG("DEBUG:modem_process: %s processing sms for net %s:" " \n\tTo:[%.*s]\n\tBody=<%d>[%.*s]\n", mdm->device, net->name, sms_messg->to.len,sms_messg->to.s, sms_messg->text.len,sms_messg->text.len,sms_messg->text.s); send_as_sms( sms_messg , mdm); counter++; /* if I reached the limit -> set not to wait */ if (counter==net->max_sms_per_call) dont_wait = 1; }/*while*/ }/*for*/ /* let's see if we have incoming sms */ if ( !cpms_unsuported ) if ((used_mem = check_memory(mdm,USED_MEM))==-1) { LOG(L_ERR,"ERROR:modem_process: CPMS command failed!" " cannot get used mem -> using 10\n"); used_mem = 10; } /* if any, let's get them */ if (used_mem) DBG("DEBUG:modem_process: %d new SMS on modem\n",used_mem); for(i=1,k=1;k<=used_mem && i<=max_mem;i++) { if (getsms(&sms,mdm,i)!=-1) { k++; DBG("SMS Get from location %d\n",i); /*for test ;-) -> to be remove*/ DBG("SMS RECEIVED:\n\rFrom: %s %s\n\r%.*s %.*s" "\n\r\"%.*s\"\n\r",sms.sender,sms.name, DATE_LEN,sms.date,TIME_LEN,sms.time, sms.userdatalength,sms.ascii); if (!sms.is_statusreport) send_sms_as_sip(&sms); else check_sms_report(&sms); } } /* if reports are used, checks for expired records in report queue */ if (sms_report_type!=NO_REPORT) check_timeout_in_report_queue(); /* sleep -> if it's needed */ if (!dont_wait) { sleep(mdm->looping_interval); } }/*while*/}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -