📄 smsc_sema.c
字号:
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 allocated 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 support"); 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 interpret"); goto error_msg; } /*status report and submit result will always be 1 segments for deliver invoke, if smsc can not send all the data in one packet, text data will be truncated ,so it's also 1 packet*/ if(imsgtopseg == 0){ info(0, "sema_decode: can not interpret more than one segments msg"); goto error_msg; } (*desmsg)->type = cmsgtype; (*desmsg)->continuebyte = cmsgcontinuebyte; (*desmsg)->encodetype = imsgencodetype; /*operation reference*/ memcpy((*desmsg)->optref, octsrc +2, 4); octsrc += 6; iusedbyte = 0; switch(cmsgtype){ case 's': /* submit invoke result */ submit_result = gw_malloc(sizeof(struct sm_submit_result)); memset(submit_result,0,sizeof(struct sm_submit_result)); /* result */ iusedbyte = line_scan_IA5_hex(octsrc, 1, tmp); if(iusedbyte < 1) goto error_submit; octetlen = 1; submit_result->smeresult = get_variable_value(tmp, &octetlen); if(submit_result->smeresult == SM_RESULT_SUCCESS) { /*smsc reference number*/ octsrc += iusedbyte; iusedbyte = line_scan_IA5_hex(octsrc, 4,tmp); if(iusedbyte <1) goto error_submit; memcpy(submit_result->smscrefnum, tmp, 4); /*accept time*/ octsrc += iusedbyte; iusedbyte = line_scan_IA5_hex(octsrc, 14,tmp); if(iusedbyte < 1) goto error_submit; memcpy(submit_result->accepttime, tmp, 4); } (*desmsg)->msgbody = (void**)&submit_result; break; case 'M': /* deliver invoke*/ receive_sm = gw_malloc(sizeof(struct sm_deliver_invoke)); memset(receive_sm, 0, sizeof(struct sm_deliver_invoke)); /*deliver destination address length*/ iusedbyte = line_scan_IA5_hex(octsrc, 1, tmp); if(iusedbyte < 1) goto error_deliver; octetlen = 1; receive_sm->destaddlen = get_variable_value(tmp, &octetlen); /*deliver destination address*/ octsrc +=iusedbyte; iusedbyte = line_scan_IA5_hex(octsrc,receive_sm->destaddlen,tmp); if(iusedbyte < 1) goto error_deliver; receive_sm->destadd= octstr_create_from_data(tmp, receive_sm->destaddlen); /*smsc reference number*/ octsrc +=iusedbyte; iusedbyte = line_scan_IA5_hex(octsrc, 4,tmp); if(iusedbyte < 1) goto error_deliver; memcpy(receive_sm->smscrefnum, tmp, 4); /*originate address length*/ octsrc +=iusedbyte; iusedbyte = line_scan_IA5_hex(octsrc, 1, tmp); if(iusedbyte < 1) goto error_deliver; octetlen = 1; receive_sm->origaddlen = get_variable_value(tmp, &octetlen); /*originate address*/ octsrc +=iusedbyte; iusedbyte = line_scan_IA5_hex(octsrc, receive_sm->origaddlen, tmp); if(iusedbyte < 1) goto error_deliver; receive_sm->origadd= octstr_create_from_data(tmp,receive_sm->origaddlen); /* data code scheme */ octsrc +=iusedbyte; if(iusedbyte < 1) goto error_deliver; iusedbyte = line_scan_IA5_hex(octsrc, 1,tmp); octetlen = 1; receive_sm->DCS = get_variable_value(tmp, &octetlen); if(receive_sm->DCS != ENCODE_IA5 && receive_sm->DCS !=ENCODE_GSM){ info(0, "sema_decode, Data encoding scheme not support"); goto error_deliver; } /* protocol */ octsrc +=iusedbyte; iusedbyte = line_scan_IA5_hex(octsrc, 1,tmp); if(iusedbyte < 1) goto error_deliver; octetlen = 1; receive_sm->protocal = get_variable_value(tmp, &octetlen); /* reply path */ octsrc +=iusedbyte; iusedbyte = line_scan_IA5_hex(octsrc, 1,tmp); if(iusedbyte < 1) goto error_deliver; octetlen = 1; receive_sm->replypath = get_variable_value(tmp, &octetlen); /*text size in septect*/ octsrc +=iusedbyte; iusedbyte = internal_char_IA5_to_hex(octsrc, tmp); if(iusedbyte < 1) goto error_deliver; receive_sm->textsizeseptet = tmp[0]; /*text size in octects*/ octsrc +=iusedbyte; iusedbyte = internal_char_IA5_to_hex(octsrc, tmp); if(iusedbyte < 1) goto error_deliver; receive_sm->textsizeoctect = tmp[0]; octsrc+=iusedbyte; /*message text*/ iusedbyte = 0; memset(tmp,0,sizeof(tmp)); if(receive_sm->DCS == ENCODE_IA5 && receive_sm->textsizeoctect > 0) { iusedbyte = line_scan_IA5_hex(octsrc,receive_sm->textsizeoctect,tmp); if(iusedbyte < 1) goto error_deliver; receive_sm->shortmsg =octstr_create_from_data( tmp,receive_sm->textsizeoctect); } else if(receive_sm->DCS == ENCODE_GSM && receive_sm->textsizeseptet > 0) { memset(tmpgsm,0,sizeof(tmpgsm)); iusedbyte = line_scan_IA5_hex(octsrc,receive_sm->textsizeoctect,tmp); if(iusedbyte < 1) goto error_deliver; line_scan_hex_GSM7(tmp,receive_sm->textsizeoctect, receive_sm->textsizeseptet, tmpgsm); receive_sm->shortmsg = octstr_create_from_data(tmpgsm, receive_sm->textsizeseptet); } else if(receive_sm->textsizeoctect <= 0) receive_sm->shortmsg = octstr_create(""); /*accepttime*/ octsrc +=iusedbyte; iusedbyte = line_scan_IA5_hex(octsrc,14,tmp); if(iusedbyte < 1) goto error_deliver; memcpy(receive_sm->accepttime, tmp,14); /*valid time*/ octsrc +=iusedbyte; iusedbyte = line_scan_IA5_hex(octsrc,14,tmp); if(iusedbyte < 1) goto error_deliver; memcpy(receive_sm->invoketime, tmp,14); (*desmsg)->msgbody = (void**)&receive_sm; break; case 'T': /* status report invoke */ receive_report = gw_malloc(sizeof(struct sm_statusreport_invoke)); memset(receive_report,0,sizeof(struct sm_statusreport_invoke)); /*deliver msisdn address length*/ iusedbyte = line_scan_IA5_hex(octsrc, 1, tmp); if(iusedbyte < 1) goto error_receive; octetlen = 1; receive_report->msisdnlen = get_variable_value(tmp, &octetlen); /*msisdn*/ octsrc += iusedbyte; iusedbyte = line_scan_IA5_hex(octsrc, receive_report->msisdnlen, tmp); if(iusedbyte < 1) goto error_receive; receive_report->msisdn = octstr_create_from_data( tmp,receive_report->msisdnlen); /*sme reference type*/ octsrc += iusedbyte; iusedbyte = line_scan_IA5_hex(octsrc, 1, tmp); if(iusedbyte < 1) goto error_receive; octetlen = 1; receive_report->smetype = get_variable_value(tmp, &octetlen); /*sme reference number */ octsrc += iusedbyte; iusedbyte = line_scan_IA5_hex(octsrc,4, tmp); if(iusedbyte < 1) goto error_receive; memcpy(receive_report->smerefnum ,tmp, 4); /*smsc reference number */ octsrc += iusedbyte; iusedbyte = line_scan_IA5_hex(octsrc,4, tmp); if(iusedbyte < 1) goto error_receive; memcpy(receive_report->smscrefnum ,tmp, 4); /*accepted time*/ octsrc += iusedbyte; iusedbyte = line_scan_IA5_hex(octsrc,14, tmp); if(iusedbyte < 1) goto error_receive; memcpy(receive_report->accepttime ,tmp, 4); /*status*/ octsrc += iusedbyte; iusedbyte = line_scan_IA5_hex(octsrc, 1, tmp); if(iusedbyte < 1) goto error_receive; octetlen = 1; receive_report->status = get_variable_value(tmp, &octetlen); octsrc += iusedbyte; if(receive_report->status != 6) /*6 means unable to deliver , but retry*/ { iusedbyte = line_scan_IA5_hex(octsrc,14, tmp); if(iusedbyte < 1) goto error_receive; memcpy(receive_report->completetime ,tmp, 14); } else { iusedbyte = line_scan_IA5_hex(octsrc,14, tmp); if(iusedbyte < 1) goto error_receive; memcpy(receive_report->intermediatime ,tmp, 14); } if(receive_report->status == 6 || receive_report->status == 1) /*unable to deliver ,both case */ { octsrc += iusedbyte; iusedbyte = line_scan_IA5_hex(octsrc, 1, tmp); if(iusedbyte < 1) goto error_receive; octetlen = 1; receive_report->failreason = get_variable_value(tmp, &octetlen); } /*deliver orignate address length*/ octsrc += iusedbyte; iusedbyte = line_scan_IA5_hex(octsrc, 1, tmp); if(iusedbyte < 1) goto error_receive; octetlen = 1; receive_report->origaddlen = get_variable_value(tmp, &octetlen); /*orignate address*/ octsrc += iusedbyte; iusedbyte = line_scan_IA5_hex(octsrc, receive_report->origaddlen, tmp); if(iusedbyte < 1) goto error_receive; receive_report->origadd = octstr_create_from_data(tmp, receive_report->msisdnlen); /* invoke time */ octsrc += iusedbyte; iusedbyte = line_scan_IA5_hex(octsrc,14, tmp); if(iusedbyte < 1){ goto error_receive; } memcpy(receive_report->invoketime ,tmp, 14); (*desmsg)->msgbody = (void**)&receive_report; break; } return 1;no_msg: info(0,"sema_decode: msg in empty"); return 0;error_receive: gw_free(receive_report); goto error_msg;error_submit: gw_free(submit_result); goto error_msg;error_deliver: gw_free(receive_sm); goto error_msg;error_msg: info(0,"sema_decode:msg parameter is not recognized or unsupported"); return 0;}static int sema_encode_msg(sema_msg* pmsg, char* str) { struct sm_submit_invoke *submit_sm = NULL; Octstr *IA5msg = NULL; int tSize = 0; unsigned char oc1byte[10]; IA5msg = octstr_create(""); switch(pmsg->type) { case 'S': submit_sm = (struct sm_submit_invoke *)(*(pmsg->msgbody)); write_variable_value(submit_sm->msisdnlen, oc1byte); /*msisdn len*/ line_append_hex_IA5(IA5msg, oc1byte,1); line_append_hex_IA5(IA5msg, octstr_get_cstr(submit_sm->msisdn), octstr_len(submit_sm->msisdn)); /*msisdn*/ write_variable_value(submit_sm->smereftype, oc1byte);/*smetype*/ line_append_hex_IA5(IA5msg, oc1byte,1); line_append_hex_IA5(IA5msg, submit_sm->smerefnum,4);/*sme reference*/ write_variable_value(submit_sm->priority, oc1byte);/*priority*/ line_append_hex_IA5(IA5msg, oc1byte,1); write_variable_value(submit_sm->origaddlen, oc1byte); /*orignating address length*/ line_append_hex_IA5(IA5msg, oc1byte,1); line_append_hex_IA5(IA5msg, octstr_get_cstr(submit_sm->origadd), octstr_len(submit_sm->origadd)); /*orignating address*/ write_variable_value(submit_sm->validperiodtype, oc1byte); /*valid period type*/ line_append_hex_IA5(IA5msg, oc1byte,1); write_variable_value(submit_sm->validperiodrela, oc1byte); /*relative period*/ line_append_hex_IA5(IA5msg, oc1byte,1); write_variable_value(submit_sm->DCS, oc1byte);/*data code scheme*/ line_append_hex_IA5(IA5msg, oc1byte,1); write_variable_value(submit_sm->statusreportrequest, oc1byte);/*request report*/ line_append_hex_IA5(IA5msg, oc1byte,1); write_variable_value(submit_sm->protocal, oc1byte);/*protocal id*/ line_append_hex_IA5(IA5msg, oc1byte, 1); write_variable_value(submit_sm->replypath, oc1byte);/*use reply path*/ line_append_hex_IA5(IA5msg, oc1byte, 1); /*text size in 7 bits char*/ tSize = internal_char_hex_to_IA5(submit_sm->textsizeseptet,oc1byte); octstr_insert_data(IA5msg, octstr_len(IA5msg), oc1byte, tSize); /*text size in 8 bits char*/ tSize = internal_char_hex_to_IA5(submit_sm->textsizeoctect,oc1byte); octstr_insert_data(IA5msg, octstr_len(IA5msg), oc1byte, tSize); line_append_hex_IA5(IA5msg, octstr_get_cstr(submit_sm->shortmsg), submit_sm->textsizeoctect); /*msg text*/ memcpy(str,octstr_get_cstr(IA5msg),octstr_len(IA5msg)); octstr_destroy(IA5msg); return 1; } return 0;}static int line_scan_hex_GSM7(unsigned char* from, int octects ,int spetets, unsigned char* to){ char* cin2 =NULL; unsigned char c; char cin7[8]; int i, pos, value; int lenin2=octects*8; cin2 = gw_malloc(lenin2); memset(cin2,48,lenin2); /*make many zeros*/ /*tranverse the octects first, so ABC -> CBA(in bin form)*/ for(i = 0; i < octects; i ++) { c = *(from + i); if(c & 1) cin2[(octects-1-i)*8 +7] = 49; if(c & 2) cin2[(octects-1-i)*8 +6] = 49; if(c & 4) cin2[(octects-1-i)*8 +5] = 49; if(c & 8) cin2[(octects-1-i)*8 +4] = 49; if(c & 16) cin2[(octects-1-i)*8 +3] = 49; if(c & 32) cin2[(octects-1-i)*8 +2] = 49; if(c & 64) cin2[(octects-1-i)*8 +1] = 49; if(c & 128) cin2[(octects-1-i)*8] = 49; } i= 1; while( i <= spetets ){ pos=lenin2 -1 -(i*7 -1); memset(cin7,0,sizeof(cin7)); memcpy(cin7, cin2 + pos, 7); value = 0; if(cin7[6] == '1') value += 1; if(cin7[5] == '1') value += 2; if(cin7[4] == '1') value += 4; if(cin7[3] == '1') value += 8; if(cin7[2] == '1') value += 16; if(cin7[1] == '1') value += 32; if(cin7[0] == '1') value += 64; to[i-1]=internal_char_hex_to_gsm(value); i +=1; } return i; }/* check SMS2000 Version 4.0 B.4.2.3 */static int line_append_hex_IA5(Octstr* des, unsigned char* src, int len){ unsigned char IA5char[3]; unsigned char tmp[1024]; int j=0; int i=0, iall=0; for(i=0; i<len; i++) { memset(IA5char, 0, sizeof(IA5char)); j=internal_char_hex_to_IA5(*(src+i),IA5char); if(j >0){ memcpy(tmp+iall,IA5char,j); iall += j; } } octstr_insert_data(des,octstr_len(des),tmp,iall); return iall;}/* check SMS2000 Version 4.0 B.4.2.3 */static int line_scan_IA5_hex(unsigned char* from, int hexnum, unsigned char* to){ unsigned char cha[1]; int cn =0, cnall = 0, i = 0; char *tmpfrom = NULL; tmpfrom = from; for(i = 0; i< hexnum; i++) { cn=internal_char_IA5_to_hex(tmpfrom, cha); if(cn >0) { memcpy(to+i,cha,1); tmpfrom += cn; cnall += cn; } else return -1; } return cnall;}static unsigned char internal_char_hex_to_gsm(unsigned char from){ switch (from){ case 0x00: return '@'; case 0x01: return '
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -