?? smsc_sema.c
字號:
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 of 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 delivered successfully to smsc"); goto mo_success; } if(sema_wait_report > 0 && isrcved == 1 && iTrcved == 1) { info(0,"sema_mt_session: submit invoke delivered successfully to msisdn"); goto mo_success; } } } }/* mo_timeout: */ info(0,"sema_mt_session: timeout without receiving all expected returns"); moret = SESSION_MT_RECEIVE_TIMEOUT; goto mo_return;mo_success: moret = SESSION_MT_RECEIVE_SUCCESS; goto mo_return;smsc_say_fail: info(0,"sema_mt_session: smsc says message deliver failed!"); moret = SESSION_MT_RECEIVE_ERR; goto mo_return;mo_return: X28_close_send_link(smsc->sema_fd); /* we have to close here, otherwise smsc will wait for a long time untill it find out nothing is coming */ sema_msg_free(mtrmsg); ilen = strlen(mochars); i = strlen(smsc->buffer); if(ilen > 0){ memmove( smsc->buffer+ilen,smsc->buffer,i); memcpy(smsc->buffer, mochars,ilen); } return moret; sendlink_error: info(0,"sema_mt_session: X28 data link has broken"); if(mtrmsg != NULL) sema_msg_free(mtrmsg); return 0;encode_error: info(0,"sema_mt_session: Msg encode error"); return 0;error: error(0,"sema_mt session: memory allocation error or device file error"); return -1;}static int sema_msg_session_mo(SMSCenter *smsc, char* cbuff){ struct sema_msg *rmsg = NULL; int iret = 0, retresult = 0; struct sm_deliver_invoke* deliver_invoke = NULL; struct sm_statusreport_invoke* report_invoke = NULL; rmsg = sema_msg_new(); iret = sema_decode_msg(&rmsg,cbuff); if(iret == - 1) goto msg_error;/* decode error */ if(x28_data_mode == X28_COMMAND_MODE){ /* do not trust any existing data mode*/ /* XXX this should be fixed? -rpr */ X28_close_send_link(smsc->sema_fd); /*open send link*/ if(X28_open_send_link(smsc->sema_fd,smsc->sema_smscnua) < 1){ info(0,"sema_mo_session: can not establish send link"); return 0; } } if(rmsg->type == 'M'){ /* deliver invoke */ retresult = 0; /* deliver invoke */ iret = sema_submit_result(smsc, rmsg, retresult); if(iret == -1) goto error; deliver_invoke = (struct sm_deliver_invoke*) rmsg->msgbody; if(deliver_invoke == NULL) goto msg_error; sema_msglist_push(smsc->sema_mo, rmsg); return 1; } else if(rmsg->type == 'T'){ /* status report */ retresult = 0; /* let msg through */ sema_submit_result(smsc, rmsg, retresult); if(iret == -1) goto error; report_invoke = (struct sm_statusreport_invoke*) rmsg->msgbody; if(report_invoke != NULL) gw_free(report_invoke); } else{ /* add your additional support here*/ } sema_msg_free(rmsg); return 1; msg_error: sema_msg_free(rmsg); error(0,"sema_mo session: Msg decode failed"); return 0;error: error(0,"sema_mo session: device file error or memory allocation problem!"); return -1;}static int sema_decode_msg(sema_msg **desmsg, char* octsrc) { struct sm_deliver_invoke *receive_sm = NULL; struct sm_statusreport_invoke* receive_report = NULL; struct sm_submit_result* submit_result = NULL; unsigned char tmp[1024],tmpgsm[1024]; int octetlen, iret, iusedbyte; int imsgtopseg = 0, imsgfollownum = 0, imsgencodetype = 0; unsigned char cmsgtype, cmsgcontinuebyte; /* message type */ if(strlen(octsrc) <= 4) goto no_msg; /* check if we support this type */ cmsgtype = *octsrc; if(cmsgtype != 's' /* invoke reseult */ && cmsgtype != 'M' /* deliver invoke */ && cmsgtype != 'T'){ /* report invoke */ info(0,"sema_decode: msg type not supported"); goto error_msg; } /*check if continue bit is correct */ cmsgcontinuebyte = *(octsrc+1); iret = unpack_continous_byte(cmsgcontinuebyte, &imsgencodetype,&imsgtopseg, &imsgfollownum); if(iret == -1){ info(0,"sema_decode: msg continue bit can not be interpreted"); goto error_msg; }
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -