⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 smsc_sema.c

📁 gnu的专业网关smpp协议支持源代码。
💻 C
📖 第 1 页 / 共 3 页
字号:
		return 1;	}    }    return 0;datalink_error:    error(errno,"sema_close_send_link, device file error");    return -1;}static int X28_open_send_link(int padfd, char *nua) {    char readbuff[1024];     char writebuff[129];    char smscbuff[129];    int readall = 0, readonce = 0, writeonce = 0, writeall = 0, i = 0;    char X28prompt[]="*\r\n\0";    time_t timestart;      debug("smsc.sema", 0, "sema_open send link: call smsc  <%s> for <%i> seconds",	  nua, (int)INTERNAL_CONNECT_TIMEVAL);	    /*  type few <cr> to invoke DTE */    writebuff[0] = '\r';           memset(readbuff,0,sizeof(readbuff));         for(i = 0; i <= 3; i++)    {	readonce = writeonce = -1;	writeonce = write(padfd, writebuff, 1);	if(writeonce < 1){	    if(errno == EINTR || errno == EAGAIN) continue;	    else{		goto datalink_error;	    }	}	usleep(1000); /* wait for prompt */	readonce = read(padfd, &readbuff[readall],1024);	if(readonce == -1){	    if(errno == EINTR || errno == EAGAIN) continue;	    else{		goto datalink_error;	    }	}	else	    readall += readonce;    }    if(strstr(readbuff, X28prompt) == NULL){	warning(0,"X28_open_send_link: can not read command prompt, abort");	return 0;    }	    /* second, connect to the smsc now */    memset(writebuff,0,sizeof(writebuff));    memset(readbuff,0,sizeof(readbuff));      writeall = readall = 0;    sprintf(writebuff, "%s\r", nua);    sprintf(smscbuff, "%s COM",nua);      while((size_t) writeall < strlen(writebuff)){	writeonce = -1;	writeonce = write(padfd, writebuff+writeall, strlen(writebuff)-writeall);	if(writeonce == -1){	    if(errno == EINTR || errno == EAGAIN)		continue;	    else		goto datalink_error;	}	if(writeonce > 0)	    writeall +=writeonce;    }    tcdrain(padfd);     usleep(1000*1000);/* wait for smsc answer */    time(&timestart);    while(time(NULL) - timestart < INTERNAL_CONNECT_TIMEVAL){	if((size_t) readall >= sizeof(readbuff))	    goto error_overflow;	/* We read 1 char a time */	readonce = read(padfd, &readbuff[readall], 1);	if(readonce == -1) {	    if(errno == EINTR || errno == EAGAIN) continue;	    else		goto datalink_error;	}	if(readonce > 0)	    readall += readonce;	/* Search for reponse line. */	if(readall > 2 &&	   readbuff[readall-1] == '\n' && 	   readbuff[readall-2] == '\r') {	    if(strstr(readbuff, smscbuff)) {		debug("smsc.sema", 0,		      "sema_open send link: smsc respond, virtual link established");		x28_data_mode = X28_MT_DATA_MODE; 		return 1;		    }	} 	usleep(1000);    }    info(0,"sema_open_send_link: connecting time out");    return 0;error_overflow:    warning(0, "sema_open_send_link: command buffer overflow");    return 0;datalink_error:    error(errno,"sema_open_send_link: device file error");    return -1;}static int X28_data_read(int padfd, char *cbuffer) {    char *p = NULL;    int ret,  len;    fd_set read_fd;    struct timeval tv, tvinit;    size_t readall;         tvinit.tv_sec = 0;    tvinit.tv_usec = 1000;         readall = 0;    for (;;) {	FD_ZERO(&read_fd);	FD_SET(padfd, &read_fd);	tv = tvinit;	ret = select(padfd + 1, &read_fd, NULL, NULL, &tv);	if (ret == -1) {	    if(errno==EINTR) goto got_data;	    if(errno==EAGAIN) goto got_data;	    error(errno, "Error doing select for fad");	    return -1;	} else if (ret == 0)	    goto got_data;	len = strlen(cbuffer);	ret = read(padfd,		   cbuffer + len,		   256);    	if (ret == -1) {            error(errno," read device file");	    return -1;	}	if (ret == 0)	    goto eof;       	readall += ret;	if ((size_t) len >  sizeof(cbuffer)- 256) {	    p = gw_realloc(cbuffer, sizeof(cbuffer) * 2);	    memset(p+len,0,sizeof(cbuffer)*2 - len);	    cbuffer = p;	}	if(readall > 0)	    break;    }     eof:    if(readall > 0)	ret = 1;    goto unblock;     got_data:    ret = 0;    goto unblock;unblock:    return ret;  }static int X28_data_send(int padfd, char *cbuffer,int sentonce) {    int len = 0, pos = 0,writeonce = 0,writeall = 0;     tcdrain(padfd);    len = strlen(cbuffer);    while(len > 0){	if(len < sentonce) {	    writeonce = write(padfd, cbuffer+pos, len);	}	else	    writeonce = write(padfd, cbuffer+pos, sentonce); 	if (writeonce == -1) {	    if(errno == EINTR || errno == EINTR)		continue;	    else{		goto error;	    }	}	if(writeonce > 0){	    len -= writeonce;	    pos += writeonce;	    writeall = pos;	}    }    tcdrain(padfd);    return writeall;error:    error(errno,"sema_send data error: device file erro");    return -1;}static int X28_msg_pop(char *from, char *to){    char* Rbuff =NULL;    char* RRbuff = NULL;    char mobuff[] ="COM\r\n\0";    char mobuffend[] = "\r\0";    char prompbuff[] = "*\r\0";    int len = 0, Llen= 0, Rlen = 0,RRlen = 0;    len = strlen(from);    if(len <=0) goto no_msg;    /* trim off rabbish header */    while(*from == '\r' || *from == '\n'){	len = strlen(from);	if(len > 1){	    memmove(from, from +1, len-1);	    memset(from+(len-1), 0, 1);	}	else{	    memset(from,0,len);	    return -1;	}    }       len = strlen(from);     /*all kinds of useful infomation contains \r*/    if((Rbuff=memchr(from,'\r',len)) == NULL)	goto no_msg;     /*check if it is a command prompt *\r\n */    if((Rbuff -from) > 0 && *(Rbuff -1) == '*'){	if(strlen(Rbuff) < 2) goto no_msg; /*\n is not coming yet*/     	if(Rbuff -from > 4){ /* command info */	    Rlen = Rbuff -1 -from;	    memcpy(to,from,Rlen);	}	x28_data_mode = X28_COMMAND_MODE;	if(strlen(Rbuff+1) > 1){	    Rlen = strlen(Rbuff +2);	    memmove(from, Rbuff +2, Rlen);	    memset(from+Rlen, 0, len-Rlen);	}	else	    memset(from, 0,len);    }/* check mo msg , format X121address+COM\r\n+msg+\r*/    else if((Rbuff-from) > 3 &&  strstr(Rbuff-4,mobuff)!= NULL){	if(strlen(Rbuff) < 3 ||	   (RRbuff = strstr(Rbuff + 2, mobuffend)) == NULL)	    goto no_msg; /*the msg+\r  is still coming*/	RRlen = RRbuff - (Rbuff+2);	if(RRlen > 4){ /* msg header is 4 byte always+msg content*/ 	    memcpy(to, Rbuff +2 , RRlen);	    x28_data_mode = X28_MO_DATA_MODE;	}	if(strlen(RRbuff) > 1){	    Rlen = strlen(RRbuff +1);	    memmove(from, RRbuff+1 ,Rlen);	    memset(from+Rlen,0,len -Rlen);	}	else	    memset(from,0,len);    }    else{/* it can be mt reply */	if(Rbuff  - from > 0){ 	    Llen = Rbuff - from;	    memcpy(to, from, Llen);	}    	if(strlen(Rbuff) > 1){	    Rlen = strlen(Rbuff+1);	    memmove(from,Rbuff+1,Rlen);	    memset(from+Rlen,0,len-Rlen);	}	else	    memset(from,0,len);    }    /* check rest line for link state: command mode or data mode */    if(strstr(from,prompbuff) != NULL)	x28_data_mode = X28_COMMAND_MODE;    return 0;no_msg:    return -1;}static int sema_submit_result(SMSCenter *smsc, sema_msg* srcmsg, int result){    char IA5buff[1024];    unsigned char oct1byte[1];    unsigned char ia5byte[2];    unsigned char cTr='t';    unsigned char cMr='m';    unsigned char ccontinuebyte = 'P', ccr = '\r';    int j = 0, iret;    memset(IA5buff,0,sizeof(IA5buff));    switch(srcmsg->type)    {    case 'M':	memcpy(IA5buff,&cMr,1);/*msg type*/	memcpy(IA5buff+1,&ccontinuebyte,1); /*continue bit*/	memcpy(IA5buff+2,srcmsg->optref,4); /*operation reference*/	write_variable_value(result,oct1byte);	j=internal_char_hex_to_IA5(oct1byte[0],ia5byte);	memcpy(IA5buff+6,ia5byte,j);	memcpy(IA5buff+6+j,&ccr,1);/*result*/	iret = X28_data_send(smsc->sema_fd,IA5buff,strlen(IA5buff));	if(iret == -1) goto error;	break;    case 'T':	memcpy(IA5buff,&cTr,1);	memcpy(IA5buff+1,&ccontinuebyte,1);	memcpy(IA5buff+2,srcmsg->optref,4); 	write_variable_value(result,oct1byte);	j=internal_char_hex_to_IA5(oct1byte[0],ia5byte);	memcpy(IA5buff+6,ia5byte,j);	memcpy(IA5buff+6+j,&ccr,1);	iret = X28_data_send(smsc->sema_fd,IA5buff,strlen(IA5buff));	if(iret == -1) goto error;	  	break;    default:  	return 0; /*unsupoorted result msg type*/    }    return 1;	error:    error(0,"sk_submit_result: write to device file failed");    return -1;}static int sema_msg_session_mt(SMSCenter *smsc, sema_msg* pmsg){    struct msg_hash *segments = NULL;    struct sema_msg* mtrmsg = NULL;    struct sm_statusreport_invoke* report_invoke = NULL;    struct sm_submit_result* submit_result = NULL;    struct sm_submit_invoke* submit_invoke = NULL;    struct sm_deliver_invoke* deliver_invoke = NULL;    char data[1024], IA5buff[256], IA5chars[1024], mochars[10*1024];    unsigned char ccontinuebyte, ccr = '\r';    unsigned char cerr[] = "ERR\0",cclr[] = "CLR\0", tmp1[5] , tmp2[5];      int  i, iseg = 0, ilen = 0,iret = 0, moret;    int isrcved = 0, iTrcved = 0, decoderesult = 0;    time_t tstart;    submit_invoke=(struct sm_submit_invoke*)(*(pmsg->msgbody));    if(submit_invoke == NULL) goto error;    /*encode first*/    memset(IA5chars,0,sizeof(IA5chars));    if(sema_encode_msg(pmsg, IA5chars) < 1) goto encode_error;    /*divide segments, we send buffer no more than 128 byte once*/    iseg = strlen(IA5chars)/121 + 1;    segments = gw_malloc(iseg * sizeof(struct msg_hash));    if(segments == NULL) goto error;    /*first segments*/	    if(strlen(IA5chars) < 121)	ilen = strlen(IA5chars);    else	ilen = 121;    segments[0].content = octstr_create_from_data(&(pmsg->type), 1);/*msg type, in hex*/    ccontinuebyte = pack_continous_byte(pmsg->encodetype, 1, iseg -1);    octstr_insert_data(segments[0].content, 1, 		       &ccontinuebyte, 1);  /*continue char, in hex*/    octstr_insert_data(segments[0].content,		       2, pmsg->optref, 4); /*operation reference, in hex*/    octstr_insert_data(segments[0].content, 6,		       IA5chars, ilen);    octstr_insert_data(segments[0].content,		       octstr_len(segments[0].content), &ccr, 1); /*<cr>*/     /*rest segments*/    for( i = 1; i < iseg; i++){	if(strlen(IA5chars) - i*121 < 121)	    ilen = strlen(IA5chars) - i*121;	else	    ilen =121;	segments[i].content= octstr_create_from_data(&(pmsg->type), 1); 	ccontinuebyte = pack_continous_byte(pmsg->encodetype, 0, iseg -i-1);	octstr_insert_data(segments[i].content, 1, &ccontinuebyte, 1); 	octstr_insert_data(segments[i].content, 2, pmsg->optref, 4); 	octstr_insert_data(segments[i].content, 6, 			   IA5chars + i*121, ilen);	octstr_insert_data(segments[i].content,			   octstr_len(segments[i].content), &ccr, 1);     }    if(x28_data_mode != X28_MT_DATA_MODE){	/* do not trust any existing data mode*/    	X28_close_send_link(smsc->sema_fd); 		/*open send link*/	if((iret = X28_open_send_link(smsc->sema_fd,smsc->sema_smscnua)) < 1){	    if(iret == -1){		iret = X28_reopen_data_link(smsc->sema_fd, smsc->sema_serialdevice);		if(iret == -1){		    goto error;		}	    }	    X28_close_send_link(smsc->sema_fd); 	    sleep(1);	    iret = X28_open_send_link(smsc->sema_fd,smsc->sema_smscnua);	    if(iret < 1)		goto sendlink_error;	}    }    /*deliver buff*/    for(i = 0; i < iseg; i++){	memset(IA5buff,0,sizeof(IA5buff));	memcpy(IA5buff,octstr_get_cstr(segments[i].content),	       octstr_len(segments[i].content));	iret =X28_data_send(smsc->sema_fd,IA5buff,strlen(IA5buff));	if(iret == -1)	    goto error;	octstr_destroy(segments[i].content);    }    gw_free(segments);    /*wait result and report return*/    mtrmsg = sema_msg_new();    memset(mochars,0,sizeof(mochars));    time(&tstart);    while(time(NULL) -tstart < INTERNAL_SESSION_MT_TIMEVAL){	iret = X28_data_read(smsc->sema_fd, smsc->buffer);	if(iret == -1)	    goto error;		/* Interpret the raw data */	memset(data,0,sizeof(data));	while(X28_msg_pop(smsc->buffer, data) == 0 ) {	    if(strlen(data) > 0){		if(strstr(data,cerr) != NULL ||		   strstr(data,cclr) != NULL){		  debug("smsc.sema", 0, "sema_mt_session: Radio Pad Command line-%s",data);		    goto sendlink_error;		}		/* decode msg*/      		decoderesult = sema_decode_msg(&mtrmsg,data);  		if(decoderesult >= 0){		    if(mtrmsg->type == 's'){ /*submit result*/	 			submit_result = (struct sm_submit_result*)(*mtrmsg->msgbody);			if(submit_result == NULL) goto error;			/* check result operation number is what we send */			memset(tmp1,0,5); memset(tmp2,0,5);			memcpy(tmp1,mtrmsg->optref,4);			memcpy(tmp2, pmsg->optref,4);			if(strstr(tmp1,tmp2) != NULL){			    isrcved = 1;			    memcpy(submit_invoke->smscrefnum, submit_result->smscrefnum,4);			}			if(isrcved == 1 &&			   submit_result->smeresult != 0){		 			    gw_free(submit_result);			    goto smsc_say_fail;  			}			gw_free(submit_result);			    } 		    else if(mtrmsg->type == 'T'){ /*report invoke*/					report_invoke=(struct sm_statusreport_invoke*)(*mtrmsg->msgbody);			if(report_invoke == NULL) goto error;			/*check if report reference number is what we expect*/			memset(tmp1,0,sizeof(tmp1)); memset(tmp2,0,sizeof(tmp2));			memcpy(tmp1,report_invoke->smscrefnum,4);			memcpy(tmp2,submit_invoke->smscrefnum,4);			if(strstr(tmp1, tmp2) != NULL){			    iTrcved = 1;			}			decoderesult = 0; 			iret = sema_submit_result(smsc, mtrmsg, decoderesult);			if(iret == -1) goto error;			if(iTrcved == 1 &&			   report_invoke->status != 3){ /*3 means ,msg delivered*/			    info(0,"sema_mt_session: submit invoke failed with report value-%i",report_invoke->status);			    gw_free(report_invoke);			    goto smsc_say_fail;			}			gw_free(report_invoke);		    }		    else if(mtrmsg->type == 'M'){/* deliver invoke*/	  			/* we do not deal with deliver in mt session*/ 			decoderesult = 0;			iret = sema_submit_result(smsc, mtrmsg, decoderesult);			if(iret == -1) goto error;			deliver_invoke =(struct sm_deliver_invoke*)(*mtrmsg->msgbody);			if(deliver_invoke != NULL){			    gw_free(deliver_invoke);			    /*append buffer back to  smsc->buffer*/			    ilen=strlen(mochars);			    memcpy(mochars+ilen,data,strlen(data));			    ilen=strlen(mochars);			    memcpy(mochars+ilen,&ccr,1);			}					time(&tstart);		    }		    /* clean msg for next read*/		    memset(mtrmsg,0,sizeof(struct sema_msg));		}		/* clean buffer for next useful info*/		memset(data,0,sizeof(data));		if(sema_wait_report == 0 && isrcved == 1)		{		    info(0,"sema_mt_session: submit invoke deliver successfully to smsc");		    goto mo_success;		}		if(sema_wait_report > 0 &&		   isrcved == 1 && iTrcved == 1)		{		    info(0,"sema_mt_session: submit invoke deliver sucessfully to msisdn");		    goto mo_success;		}	    }	}    }/* mo_timeout: */      info(0,"sema_mt_session: time out without receive all expected return");      moret = SESSION_MT_RECEIVE_TIMEOUT;      goto mo_return;mo_success:    moret = SESSION_MT_RECEIVE_SUCCESS;    goto mo_return;smsc_say_fail:

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -