00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079 #include <errno.h>
00080 #include <stdarg.h>
00081 #include <stdio.h>
00082 #include <stdlib.h>
00083 #include <string.h>
00084 #include <unistd.h>
00085 #include <fcntl.h>
00086 #include <termios.h>
00087
00088 #include <sys/time.h>
00089 #include <sys/types.h>
00090 #include <sys/socket.h>
00091 #include <sys/param.h>
00092
00093
00094 #include <netinet/in.h>
00095 #include <netdb.h>
00096
00097 #include "gwlib/gwlib.h"
00098 #include "smsc.h"
00099 #include "smsc_p.h"
00100 #include "alt_charsets.h"
00101 #include "smsc_sema.h"
00102 #include "sms.h"
00103
00104 #ifndef CRTSCTS
00105 #define CRTSCTS 0
00106 #endif
00107
00108
00109 static unsigned char sema_counter[4] = "0000";
00110 static int sema_wait_report = 1;
00111 static int x28_data_mode = X28_COMMAND_MODE;
00112
00113 SMSCenter * sema_open(char* smscnua, char* homenua,
00114 char* serialdevice, int waitreport)
00115 {
00116 SMSCenter *smsc;
00117 int nret = -1;
00118
00119 smsc = smscenter_construct();
00120 if(smsc == NULL)
00121 goto error;
00122
00123 sprintf(smsc->name, "SEMA:X28:");
00124
00125 smsc->type = SMSC_TYPE_SEMA_X28;
00126 smsc->sema_smscnua = gw_strdup(smscnua);
00127 smsc->sema_homenua = gw_strdup(homenua);
00128 smsc->sema_serialdevice = gw_strdup(serialdevice);
00129 sema_wait_report = waitreport;
00130
00131 smsc->sema_mt = sema_msglist_new();
00132 if(smsc->sema_mt == NULL) goto error;
00133
00134 smsc->sema_mo = sema_msglist_new();
00135 if(smsc->sema_mo == NULL) goto error;
00136
00137
00138
00139 debug("smsc.sema", 0, "sema_open: open datalink");
00140 smsc->sema_fd = X28_open_data_link(smsc->sema_serialdevice);
00141 if(smsc->sema_fd == -1) goto error;
00142
00143
00144 debug("smsc.sema", 0, "sema_open: test send link");
00145 nret = X28_open_send_link(smsc->sema_fd, smsc->sema_smscnua);
00146 if(nret < 1){
00147 sleep(2);
00148 nret = X28_open_send_link(smsc->sema_fd, smsc->sema_smscnua);
00149 if(nret < 1)
00150 goto error;
00151 }
00152 X28_close_send_link(smsc->sema_fd);
00153 return smsc;
00154
00155 error:
00156 error(0, "sema_open: could not open");
00157 smscenter_destruct(smsc);
00158 return NULL;
00159 }
00160
00161
00162 int sema_reopen(SMSCenter *smsc)
00163 {
00164 int nret = 0;
00165
00166 debug("smsc.sema", 0, "reopening the connection");
00167
00168
00169 sema_msglist_free(smsc->sema_mt);
00170 sema_msglist_free(smsc->sema_mo);
00171
00172 smsc->sema_mt = sema_msglist_new();
00173 if(smsc->sema_mt == NULL) goto error;
00174 smsc->sema_mo = sema_msglist_new();
00175 if(smsc->sema_mo == NULL) goto error;
00176 memset(smsc->buffer,0,sizeof(smsc->buffer));
00177
00178
00179
00180 smsc->sema_fd = X28_reopen_data_link(smsc->sema_fd, smsc->sema_serialdevice);
00181 if(smsc->sema_fd == -1){
00182 error(0,"sema_reopen_data_link: device file error");
00183 goto error;
00184 }
00185
00186 nret = X28_open_send_link(smsc->sema_fd, smsc->sema_smscnua);
00187 if(nret < 1){
00188 error(0,"test send data link failed");
00189 goto error;
00190 }
00191 X28_close_send_link(smsc->sema_fd);
00192 return 0;
00193 error:
00194 error(0, "sema_reopen_data_link: failed");
00195 return -1;
00196
00197 }
00198
00199 int sema_close(SMSCenter *smsc)
00200 {
00201 if(smsc->sema_fd > 0)
00202 close(smsc->sema_fd);
00203
00204 sema_msglist_free(smsc->sema_mt);
00205 sema_msglist_free(smsc->sema_mo);
00206 return 0;
00207 }
00208
00209
00210 int sema_submit_msg(SMSCenter *smsc, Msg *msg)
00211 {
00212 int nret = 0;
00213 struct sema_msg *lmsg = NULL;
00214 struct sm_submit_invoke *submit_sm = NULL;
00215 char x28sender[2] = "A3";
00216
00217
00218 if(smsc == NULL){
00219 error(0,"sema_submit_msg: SMSC is empty");
00220 goto error;
00221 }
00222 if(msg == NULL){
00223 error(0, "sema_submit_msg: Msg is empty");
00224 goto error;
00225 }
00226
00227 if(msg_type(msg) != sms) {
00228 error(0, "sema_submit_sms: Msg is WRONG TYPE");
00229 goto error;
00230 }
00231
00232
00233
00234
00235
00236
00237
00238
00239
00240
00241
00242 lmsg = sema_msg_new();
00243
00244 submit_sm = gw_malloc(sizeof(struct sm_submit_invoke));
00245 memset(submit_sm, 0, sizeof(struct sm_submit_invoke));
00246
00247 lmsg->type = 'S';
00248 lmsg->encodetype = LINE_ENCODE_IA5;
00249
00250
00251 increment_counter();
00252 memcpy(lmsg->optref,sema_counter,4);
00253
00254 increment_counter();
00255 memcpy(submit_sm->smerefnum, sema_counter, 4);
00256
00257 submit_sm->smereftype= 2;
00258
00259 submit_sm->priority = 1;
00260
00261 submit_sm->validperiodtype = 2;
00262
00263 submit_sm->validperiodrela = 1;
00264
00265 submit_sm->msisdnlen= octstr_len(msg->sms.receiver);
00266 submit_sm->msisdn = octstr_copy(msg->sms.receiver,0,submit_sm->msisdnlen);
00267
00268 submit_sm->origaddlen= 2;
00269 submit_sm->origadd = octstr_create_from_data(x28sender,2);
00270
00271 submit_sm->DCS = 15;
00272
00273 submit_sm->protocal = 0;
00274
00275 submit_sm->replypath= 0;
00276
00277 if(sema_wait_report > 0)
00278 submit_sm->statusreportrequest =4;
00279 else
00280 submit_sm->statusreportrequest = 0;
00281
00282 submit_sm->textsizeoctect = submit_sm->textsizeseptet =
00283 octstr_len(msg->sms.msgdata);
00284
00285 submit_sm->shortmsg = octstr_copy(msg->sms.msgdata,
00286 0, submit_sm->textsizeoctect);
00287
00288 memset(submit_sm->smscrefnum,0,sizeof(submit_sm->smscrefnum));
00289
00290 lmsg->msgbody = submit_sm;
00291 nret = sema_msg_session_mt(smsc, lmsg);
00292
00293 gw_free(submit_sm);
00294 submit_sm = NULL;
00295 sema_msg_free(lmsg);
00296 lmsg = NULL;
00297
00298
00299 if(nret == SESSION_MT_RECEIVE_SUCCESS){
00300 debug("smsc.sema", 0, "sema_submit_msg: message is successfully delivered");
00301 return 1;
00302 }
00303 else if(nret == SESSION_MT_RECEIVE_TIMEOUT){
00304 info(0, "sema_submit msg: session timed out without return");
00305 return 0;
00306 }
00307 else if(nret == SESSION_MT_RECEIVE_ERR){
00308 info(0, "sema_submit msg: smsc says submit failed!");
00309 return 0;
00310 }
00311
00312 return 1;
00313
00314 error:
00315 if(submit_sm)
00316 gw_free(submit_sm);
00317 if(lmsg)
00318 sema_msg_free(lmsg);
00319 return -1;
00320 }
00321
00322
00323 int sema_receive_msg(SMSCenter *smsc, Msg **msg)
00324 {
00325
00326 struct sema_msg *rmsg = NULL;
00327 struct sm_deliver_invoke *recieve_sm = NULL;
00328
00329 while(sema_msglist_pop(smsc->sema_mo, &rmsg) == 1 ) {
00330
00331 *msg = msg_create(sms);
00332 if(*msg==NULL) goto error;
00333
00334 recieve_sm = (struct sm_deliver_invoke*) rmsg->msgbody;
00335 if(recieve_sm==NULL) goto error;
00336
00337
00338
00339
00340
00341 (*msg)->sms.coding = DC_8BIT;
00342
00343
00344 (*msg)->sms.sender = octstr_create_from_data(
00345 octstr_get_cstr(recieve_sm->origadd) +2,
00346 octstr_len(recieve_sm->origadd)-2);
00347 (*msg)->sms.receiver = octstr_create_from_data(
00348 octstr_get_cstr(recieve_sm->destadd) +2,
00349 octstr_len(recieve_sm->destadd)-2);
00350
00351 (*msg)->sms.msgdata = octstr_duplicate(recieve_sm->shortmsg);
00352 (*msg)->sms.udhdata = octstr_create("");
00353 gw_free(recieve_sm);
00354 sema_msg_free(rmsg);
00355 rmsg = NULL;
00356 }
00357 return 1;
00358
00359 error:
00360 error(0, "sema_receive_msg: can not create Smart Msg");
00361 return -1;
00362 }
00363
00364
00365 int sema_pending_smsmessage(SMSCenter *smsc)
00366 {
00367
00368 char data[1024];
00369 int ret = 0;
00370 char clrbuff[]="CLR\0";
00371 char errbuff[]="ERR\0";
00372
00373
00374
00375 ret = X28_data_read(smsc->sema_fd, smsc->buffer);
00376 if(ret == -1) {
00377 ret = X28_reopen_data_link(smsc->sema_fd, smsc->sema_serialdevice);
00378 if(ret == -1) goto error;
00379 return 0;
00380 }
00381
00382
00383 memset(data,0,sizeof(data));
00384 while(X28_msg_pop(smsc->buffer, data) == 0 ) {
00385 if(strlen(data) > 0){
00386 if(strstr(data,clrbuff) != NULL ||
00387 strstr(data,errbuff) != NULL){
00388 debug("smsc.sema", 0, "sema_pending_msg: Radio Pad Command line-%s",data);
00389 }
00390 else{
00391
00392 ret = sema_msg_session_mo(smsc, data);
00393 if(ret == -1) goto error;
00394 }
00395 memset(data,0,sizeof(data));
00396 }
00397 }
00398
00399
00400 if(smsc->sema_mo->first != NULL){
00401 return 1;
00402 }
00403
00404
00405 return 0;
00406
00407 error:
00408 error(0,"sema_pending message: device file error");
00409 return -1;
00410 }
00411
00412
00413
00414 static sema_msg* sema_msg_new(void)
00415 {
00416 struct sema_msg *msg = NULL;
00417 msg = gw_malloc(sizeof(struct sema_msg));
00418 memset(msg, 0, sizeof(struct sema_msg));
00419 return msg;
00420 }
00421
00422 static int sema_msg_free(sema_msg *msg) {
00423 if(msg == NULL) return 0;
00424 gw_free(msg);
00425 return 1;
00426 }
00427
00428 static sema_msglist* sema_msglist_new(void) {
00429
00430 struct sema_msglist *mlist = NULL;
00431 mlist = gw_malloc(sizeof(struct sema_msglist));
00432 memset(mlist, 0, sizeof(struct sema_msglist));
00433
00434 mlist->first = NULL;
00435 mlist->last = NULL;
00436 mlist->count = 0;
00437 return mlist;
00438 }
00439
00440 static void sema_msglist_free(sema_msglist *mlist) {
00441
00442 struct sema_msg *pmsg = NULL;
00443 if(mlist == NULL) return;
00444 while( sema_msglist_pop(mlist, &pmsg) == 1 ) {
00445 if(pmsg==NULL) break;
00446 sema_msg_free(pmsg);
00447 pmsg = NULL;
00448 }
00449 gw_free(mlist);
00450 mlist->count = 0;
00451 }
00452
00453 static int sema_msglist_push(sema_msglist *plist, sema_msg *pmsg) {
00454
00455 struct sema_msg * lmsg = NULL;
00456 if(plist == NULL) {
00457 info(0, "msglist_push: NULL msg list");
00458 goto error;
00459 }
00460 if(pmsg == NULL) {
00461 info(0, "msglist_push: NULL input");
00462 goto error;
00463 }
00464
00465 if( plist->first == NULL ) {
00466 plist->last = pmsg;
00467 plist->first = pmsg;
00468 pmsg->prev = NULL;
00469 pmsg->next = NULL;
00470 }
00471 else{
00472 lmsg=plist->last;
00473 lmsg->next=pmsg;
00474 pmsg->prev=lmsg;
00475 pmsg->next=NULL;
00476 plist->last=pmsg;
00477 }
00478 plist->count += 1;
00479 return 1;
00480
00481 error:
00482 error(0, "msglist_push: error");
00483 return 0;
00484
00485 }
00486
00487 static int sema_msglist_pop(sema_msglist *plist, sema_msg **msg) {
00488
00489 if(plist == NULL) {
00490 info(0, "msglist_pop: NULL list");
00491 goto no_msg;
00492 }
00493 if(plist->first == NULL) {
00494 goto no_msg;
00495 }
00496
00497 *msg = plist->first;
00498 if(plist->last == *msg) {
00499 plist->first = NULL;
00500 (*msg)->prev = NULL;
00501 plist->last = NULL;
00502 }
00503 else {
00504 plist->first = (*msg)->next;
00505 plist->first->prev = NULL;
00506 if(plist->first->next == NULL)
00507 plist->last = plist->first;
00508 }
00509 plist->count -= 1;
00510 return 1;
00511
00512 no_msg:
00513 return 0;
00514 }
00515
00516
00517
00518 static int X28_open_data_link(char* device){
00519 int fd = -1, iret;
00520 struct termios tios;
00521 info(0,"open serial device %s",device);
00522 fd = open(device, O_RDWR|O_NONBLOCK|O_NOCTTY);
00523 if(fd==-1) {
00524 error(errno, "sema_open_data_link: error open(2)ing the character device <%s>",
00525 device);
00526 if(errno == EACCES)
00527 error(0, "sema_open_data_link: user has no right to access the serial device");
00528 return -1;
00529 }
00530
00531 tcgetattr(fd, &tios);
00532 cfsetospeed(&tios, B4800);
00533 cfsetispeed(&tios, B4800);
00534 kannel_cfmakeraw(&tios);
00535 tios.c_iflag |= IGNBRK|IGNPAR|INPCK|ISTRIP;
00536 tios.c_cflag |= (CSIZE|HUPCL | CREAD | CRTSCTS);
00537 tios.c_cflag ^= PARODD;
00538 tios.c_cflag |=CS7;
00539 iret = tcsetattr(fd, TCSANOW, &tios);
00540 if(iret == -1){
00541 error(errno,"sema_open_data_link: fail to set termios attribute");
00542 goto error;
00543 }
00544 tcflush(fd, TCIOFLUSH);
00545 return fd;
00546
00547 error:
00548 return -1;
00549 }
00550
00551 static int X28_reopen_data_link(int oldpadfd ,char* device){
00552 int nret = 0;
00553 if(oldpadfd > 0){
00554 nret= close(oldpadfd);
00555 if(nret == -1){
00556 error(errno,"sema_reopen_data_link: close device file failed!!");
00557 }
00558 }
00559 sleep(1);
00560 return X28_open_data_link(device);
00561 }
00562
00563
00564 static int X28_close_send_link(int padfd)
00565 {
00566 char discnntbuff[5];
00567 char readbuff[1024];
00568 char finishconfirm[]="CLR CONF\0";
00569 int nret = 0, readall = 0;
00570 time_t tstart;
00571 time(&tstart);
00572
00573 sprintf(discnntbuff,"%cCLR\r",0x10);
00574 memset(readbuff,0,sizeof(readbuff));
00575
00576
00577 x28_data_mode = X28_COMMAND_MODE;
00578
00579 if(padfd <= 0)
00580 goto datalink_error;
00581 while((time(NULL) - tstart) < INTERNAL_DISCONNECT_TIMEVAL){
00582 nret =write(padfd, discnntbuff, 5);
00583 if(nret == -1){
00584 if(errno == EAGAIN || errno ==EINTR) continue;
00585 else{
00586 goto datalink_error;
00587 }
00588 }
00589 sleep(1);
00590 nret=read(padfd, readbuff+readall,128);
00591 if(nret == -1){
00592 if(errno == EAGAIN || errno ==EINTR) continue;
00593 else{
00594 goto datalink_error;
00595 }
00596 }
00597 if(nret >0){
00598 readall += nret;
00599 if(strstr(readbuff,finishconfirm))
00600 return 1;
00601 }
00602 }
00603 return 0;
00604 datalink_error:
00605 error(errno,"sema_close_send_link, device file error");
00606 return -1;
00607 }
00608
00609
00610
00611 static int X28_open_send_link(int padfd, char *nua) {
00612
00613 char readbuff[1024];
00614 char writebuff[129];
00615 char smscbuff[129];
00616 int readall = 0, readonce = 0, writeonce = 0, writeall = 0, i = 0;
00617 char X28prompt[]="*\r\n\0";
00618 time_t timestart;
00619
00620 debug("smsc.sema", 0, "sema_open send link: call smsc <%s> for <%i> seconds",
00621 nua, (int)INTERNAL_CONNECT_TIMEVAL);
00622
00623
00624 writebuff[0] = '\r';
00625 memset(readbuff,0,sizeof(readbuff));
00626 for(i = 0; i <= 3; i++)
00627 {
00628 readonce = writeonce = -1;
00629 writeonce = write(padfd, writebuff, 1);
00630 if(writeonce < 1){
00631 if(errno == EINTR || errno == EAGAIN) continue;
00632 else{
00633 goto datalink_error;
00634 }
00635 }
00636 usleep(1000);
00637 readonce = read(padfd, &readbuff[readall],1024);
00638 if(readonce == -1){
00639 if(errno == EINTR || errno == EAGAIN) continue;
00640 else{
00641 goto datalink_error;
00642 }
00643 }
00644 else
00645 readall += readonce;
00646 }
00647 if(strstr(readbuff, X28prompt) == NULL){
00648 warning(0,"X28_open_send_link: can not read command prompt, abort");
00649 return 0;
00650 }
00651
00652
00653
00654 memset(writebuff,0,sizeof(writebuff));
00655 memset(readbuff,0,sizeof(readbuff));
00656 writeall = readall = 0;
00657 sprintf(writebuff, "%s\r", nua);
00658 sprintf(smscbuff, "%s COM",nua);
00659
00660 while((size_t) writeall < strlen(writebuff)){
00661 writeonce = -1;
00662 writeonce = write(padfd, writebuff+writeall, strlen(writebuff)-writeall);
00663 if(writeonce == -1){
00664 if(errno == EINTR || errno == EAGAIN)
00665 continue;
00666 else
00667 goto datalink_error;
00668 }
00669 if(writeonce > 0)
00670 writeall +=writeonce;
00671 }
00672 tcdrain(padfd);
00673 usleep(1000*1000);
00674
00675 time(×tart);
00676 while(time(NULL) - timestart < INTERNAL_CONNECT_TIMEVAL){
00677 if((size_t) readall >= sizeof(readbuff))
00678 goto error_overflow;
00679
00680 readonce = read(padfd, &readbuff[readall], 1);
00681 if(readonce == -1) {
00682 if(errno == EINTR || errno == EAGAIN) continue;
00683 else
00684 goto datalink_error;
00685 }
00686 if(readonce > 0)
00687 readall += readonce;
00688
00689 if(readall > 2 &&
00690 readbuff[readall-1] == '\n' &&
00691 readbuff[readall-2] == '\r') {
00692 if(strstr(readbuff, smscbuff)) {
00693 debug("smsc.sema", 0,
00694 "sema_open send link: smsc responded, virtual link established");
00695 x28_data_mode = X28_MT_DATA_MODE;
00696 return 1;
00697 }
00698 }
00699 usleep(1000);
00700 }
00701 info(0,"sema_open_send_link: connect timeout");
00702 return 0;
00703 error_overflow:
00704 warning(0, "sema_open_send_link: command buffer overflow");
00705 return 0;
00706 datalink_error:
00707 error(errno,"sema_open_send_link: device file error");
00708 return -1;
00709 }
00710
00711
00712
00713 static int X28_data_read(int padfd, char *cbuffer) {
00714 char *p = NULL;
00715 int ret, len;
00716 fd_set read_fd;
00717 struct timeval tv, tvinit;
00718 size_t readall;
00719
00720 tvinit.tv_sec = 0;
00721 tvinit.tv_usec = 1000;
00722
00723 readall = 0;
00724 for (;;) {
00725 FD_ZERO(&read_fd);
00726 FD_SET(padfd, &read_fd);
00727 tv = tvinit;
00728 ret = select(padfd + 1, &read_fd, NULL, NULL, &tv);
00729 if (ret == -1) {
00730 if(errno==EINTR) goto got_data;
00731 if(errno==EAGAIN) goto got_data;
00732 error(errno, "Error doing select for fad");
00733 return -1;
00734 } else if (ret == 0)
00735 goto got_data;
00736 len = strlen(cbuffer);
00737 ret = read(padfd,
00738 cbuffer + len,
00739 256);
00740 if (ret == -1) {
00741 error(errno," read device file");
00742 return -1;
00743 }
00744 if (ret == 0)
00745 goto eof;
00746
00747 readall += ret;
00748 if ((size_t) len > sizeof(cbuffer)- 256) {
00749 p = gw_realloc(cbuffer, sizeof(cbuffer) * 2);
00750 memset(p+len,0,sizeof(cbuffer)*2 - len);
00751 cbuffer = p;
00752 }
00753 if(readall > 0)
00754 break;
00755 }
00756
00757 eof:
00758 if(readall > 0)
00759 ret = 1;
00760 goto unblock;
00761
00762 got_data:
00763 ret = 0;
00764 goto unblock;
00765
00766 unblock:
00767 return ret;
00768
00769 }
00770
00771 static int X28_data_send(int padfd, char *cbuffer,int sentonce) {
00772 int len = 0, pos = 0,writeonce = 0,writeall = 0;
00773
00774 tcdrain(padfd);
00775 len = strlen(cbuffer);
00776 while(len > 0){
00777 if(len < sentonce) {
00778 writeonce = write(padfd, cbuffer+pos, len);
00779 }
00780 else
00781 writeonce = write(padfd, cbuffer+pos, sentonce);
00782
00783 if (writeonce == -1) {
00784 if(errno == EINTR || errno == EINTR)
00785 continue;
00786 else{
00787 goto error;
00788 }
00789 }
00790 if(writeonce > 0){
00791 len -= writeonce;
00792 pos += writeonce;
00793 writeall = pos;
00794 }
00795 }
00796 tcdrain(padfd);
00797 return writeall;
00798
00799 error:
00800 error(errno,"sema_send data error: device file error");
00801 return -1;
00802 }
00803
00804 static int X28_msg_pop(char *from, char *to)
00805 {
00806 char* Rbuff =NULL;
00807 char* RRbuff = NULL;
00808 char mobuff[] ="COM\r\n\0";
00809 char mobuffend[] = "\r\0";
00810 char prompbuff[] = "*\r\0";
00811 int len = 0, Llen= 0, Rlen = 0,RRlen = 0;
00812
00813 len = strlen(from);
00814 if(len <=0) goto no_msg;
00815
00816
00817 while(*from == '\r' || *from == '\n'){
00818 len = strlen(from);
00819 if(len > 1){
00820 memmove(from, from +1, len-1);
00821 memset(from+(len-1), 0, 1);
00822 }
00823 else{
00824 memset(from,0,len);
00825 return -1;
00826 }
00827 }
00828
00829 len = strlen(from);
00830
00831 if((Rbuff=memchr(from,'\r',len)) == NULL)
00832 goto no_msg;
00833
00834
00835
00836 if((Rbuff -from) > 0 && *(Rbuff -1) == '*'){
00837 if(strlen(Rbuff) < 2) goto no_msg;
00838
00839 if(Rbuff -from > 4){
00840 Rlen = Rbuff -1 -from;
00841 memcpy(to,from,Rlen);
00842 }
00843 x28_data_mode = X28_COMMAND_MODE;
00844 if(strlen(Rbuff+1) > 1){
00845 Rlen = strlen(Rbuff +2);
00846 memmove(from, Rbuff +2, Rlen);
00847 memset(from+Rlen, 0, len-Rlen);
00848 }
00849 else
00850 memset(from, 0,len);
00851 }
00852 else if((Rbuff-from) > 3 && strstr(Rbuff-4,mobuff)!= NULL){
00853 if(strlen(Rbuff) < 3 ||
00854 (RRbuff = strstr(Rbuff + 2, mobuffend)) == NULL)
00855 goto no_msg;
00856
00857 RRlen = RRbuff - (Rbuff+2);
00858 if(RRlen > 4){
00859 memcpy(to, Rbuff +2 , RRlen);
00860 x28_data_mode = X28_MO_DATA_MODE;
00861 }
00862
00863 if(strlen(RRbuff) > 1){
00864 Rlen = strlen(RRbuff +1);
00865 memmove(from, RRbuff+1 ,Rlen);
00866 memset(from+Rlen,0,len -Rlen);
00867 }
00868 else
00869 memset(from,0,len);
00870 }
00871 else{
00872 if(Rbuff - from > 0){
00873 Llen = Rbuff - from;
00874 memcpy(to, from, Llen);
00875 }
00876 if(strlen(Rbuff) > 1){
00877 Rlen = strlen(Rbuff+1);
00878 memmove(from,Rbuff+1,Rlen);
00879 memset(from+Rlen,0,len-Rlen);
00880 }
00881 else
00882 memset(from,0,len);
00883 }
00884
00885
00886 if(strstr(from,prompbuff) != NULL)
00887 x28_data_mode = X28_COMMAND_MODE;
00888
00889 return 0;
00890 no_msg:
00891 return -1;
00892 }
00893
00894
00895
00896 static int sema_submit_result(SMSCenter *smsc, sema_msg* srcmsg, int result)
00897 {
00898 char IA5buff[1024];
00899 unsigned char oct1byte[1];
00900 unsigned char ia5byte[2];
00901 unsigned char cTr='t';
00902 unsigned char cMr='m';
00903 unsigned char ccontinuebyte = 'P', ccr = '\r';
00904 int j = 0, iret;
00905
00906 memset(IA5buff,0,sizeof(IA5buff));
00907 switch(srcmsg->type)
00908 {
00909 case 'M':
00910 memcpy(IA5buff,&cMr,1);
00911 memcpy(IA5buff+1,&ccontinuebyte,1);
00912 memcpy(IA5buff+2,srcmsg->optref,4);
00913 write_variable_value(result,oct1byte);
00914 j=internal_char_hex_to_IA5(oct1byte[0],ia5byte);
00915 memcpy(IA5buff+6,ia5byte,j);
00916 memcpy(IA5buff+6+j,&ccr,1);
00917 iret = X28_data_send(smsc->sema_fd,IA5buff,strlen(IA5buff));
00918 if(iret == -1) goto error;
00919 break;
00920 case 'T':
00921 memcpy(IA5buff,&cTr,1);
00922 memcpy(IA5buff+1,&ccontinuebyte,1);
00923 memcpy(IA5buff+2,srcmsg->optref,4);
00924 write_variable_value(result,oct1byte);
00925 j=internal_char_hex_to_IA5(oct1byte[0],ia5byte);
00926 memcpy(IA5buff+6,ia5byte,j);
00927 memcpy(IA5buff+6+j,&ccr,1);
00928 iret = X28_data_send(smsc->sema_fd,IA5buff,strlen(IA5buff));
00929 if(iret == -1) goto error;
00930 break;
00931 default:
00932 return 0;
00933 }
00934 return 1;
00935 error:
00936 error(0,"sk_submit_result: write to device file failed");
00937 return -1;
00938 }
00939
00940 static int sema_msg_session_mt(SMSCenter *smsc, sema_msg* pmsg){
00941 struct msg_hash *segments = NULL;
00942 struct sema_msg* mtrmsg = NULL;
00943 struct sm_statusreport_invoke* report_invoke = NULL;
00944 struct sm_submit_result* submit_result = NULL;
00945 struct sm_submit_invoke* submit_invoke = NULL;
00946 struct sm_deliver_invoke* deliver_invoke = NULL;
00947
00948 char data[1024], IA5buff[256], IA5chars[1024], mochars[10*1024];
00949 unsigned char ccontinuebyte, ccr = '\r';
00950 unsigned char cerr[] = "ERR\0",cclr[] = "CLR\0", tmp1[5] , tmp2[5];
00951
00952 int i, iseg = 0, ilen = 0,iret = 0, moret;
00953 int isrcved = 0, iTrcved = 0, decoderesult = 0;
00954 time_t tstart;
00955
00956 submit_invoke = (struct sm_submit_invoke*) pmsg->msgbody;
00957 if(submit_invoke == NULL) goto error;
00958
00959
00960 memset(IA5chars,0,sizeof(IA5chars));
00961
00962 if(sema_encode_msg(pmsg, IA5chars) < 1) goto encode_error;
00963
00964
00965 iseg = strlen(IA5chars)/121 + 1;
00966 segments = gw_malloc(iseg * sizeof(struct msg_hash));
00967 if(segments == NULL) goto error;
00968
00969
00970
00971 if(strlen(IA5chars) < 121)
00972 ilen = strlen(IA5chars);
00973 else
00974 ilen = 121;
00975 segments[0].content = octstr_create_from_data((char *)&(pmsg->type), 1);
00976 ccontinuebyte = pack_continous_byte(pmsg->encodetype, 1, iseg -1);
00977 octstr_insert_data(segments[0].content, 1,
00978 (char *)&ccontinuebyte, 1);
00979 octstr_insert_data(segments[0].content,
00980 2, (char *)pmsg->optref, 4);
00981 octstr_insert_data(segments[0].content, 6,
00982 IA5chars, ilen);
00983 octstr_insert_data(segments[0].content,
00984 octstr_len(segments[0].content), (char *)&ccr, 1);
00985
00986
00987 for( i = 1; i < iseg; i++){
00988 if(strlen(IA5chars) - i*121 < 121)
00989 ilen = strlen(IA5chars) - i*121;
00990 else
00991 ilen =121;
00992 segments[i].content= octstr_create_from_data((char *)&(pmsg->type), 1);
00993 ccontinuebyte = pack_continous_byte(pmsg->encodetype, 0, iseg -i-1);
00994 octstr_insert_data(segments[i].content, 1, (char *)&ccontinuebyte, 1);
00995 octstr_insert_data(segments[i].content, 2, (char *)pmsg->optref, 4);
00996 octstr_insert_data(segments[i].content, 6,
00997 IA5chars + i*121, ilen);
00998 octstr_insert_data(segments[i].content,
00999 octstr_len(segments[i].content),(char *)&ccr, 1);
01000 }
01001
01002 if(x28_data_mode != X28_MT_DATA_MODE){
01003
01004 X28_close_send_link(smsc->sema_fd);
01005
01006 if((iret = X28_open_send_link(smsc->sema_fd,smsc->sema_smscnua)) < 1){
01007 if(iret == -1){
01008 iret = X28_reopen_data_link(smsc->sema_fd, smsc->sema_serialdevice);
01009 if(iret == -1){
01010 goto error;
01011 }
01012 }
01013 X28_close_send_link(smsc->sema_fd);
01014 sleep(1);
01015 iret = X28_open_send_link(smsc->sema_fd,smsc->sema_smscnua);
01016 if(iret < 1)
01017 goto sendlink_error;
01018 }
01019 }
01020
01021 for(i = 0; i < iseg; i++){
01022 memset(IA5buff,0,sizeof(IA5buff));
01023 memcpy(IA5buff,octstr_get_cstr(segments[i].content),
01024 octstr_len(segments[i].content));
01025
01026 iret =X28_data_send(smsc->sema_fd,IA5buff,strlen(IA5buff));
01027 if(iret == -1)
01028 goto error;
01029 octstr_destroy(segments[i].content);
01030 }
01031 gw_free(segments);
01032
01033
01034 mtrmsg = sema_msg_new();
01035 memset(mochars,0,sizeof(mochars));
01036
01037 time(&tstart);
01038 while(time(NULL) -tstart < INTERNAL_SESSION_MT_TIMEVAL){
01039 iret = X28_data_read(smsc->sema_fd, smsc->buffer);
01040 if(iret == -1)
01041 goto error;
01042
01043
01044 memset(data,0,sizeof(data));
01045 while(X28_msg_pop(smsc->buffer, data) == 0 ) {
01046 if(strlen(data) > 0){
01047 if(strstr(data,(char *)cerr) != NULL ||
01048 strstr(data,(char *)cclr) != NULL){
01049 debug("smsc.sema", 0, "sema_mt_session: Radio Pad Command line-%s",data);
01050 goto sendlink_error;
01051 }
01052
01053 decoderesult = sema_decode_msg(&mtrmsg,data);
01054 if(decoderesult >= 0){
01055 if(mtrmsg->type == 's'){
01056
01057 submit_result = (struct sm_submit_result*) mtrmsg->msgbody;
01058 if(submit_result == NULL) goto error;
01059
01060 memset(tmp1,0,5); memset(tmp2,0,5);
01061 memcpy(tmp1,mtrmsg->optref,4);
01062 memcpy(tmp2, pmsg->optref,4);
01063 if(strstr((char *)tmp1,(char *)tmp2) != NULL){
01064 isrcved = 1;
01065 memcpy(submit_invoke->smscrefnum, submit_result->smscrefnum,4);
01066 }
01067 if(isrcved == 1 &&
01068 submit_result->smeresult != 0){
01069 gw_free(submit_result);
01070 goto smsc_say_fail;
01071 }
01072 gw_free(submit_result);
01073
01074 }
01075 else if(mtrmsg->type == 'T'){
01076
01077 report_invoke = (struct sm_statusreport_invoke*) mtrmsg->msgbody;
01078 if(report_invoke == NULL) goto error;
01079
01080 memset(tmp1,0,sizeof(tmp1)); memset(tmp2,0,sizeof(tmp2));
01081 memcpy(tmp1,report_invoke->smscrefnum,4);
01082 memcpy(tmp2,submit_invoke->smscrefnum,4);
01083 if(strstr((char *)tmp1,(char *)tmp2) != NULL){
01084 iTrcved = 1;
01085 }
01086 decoderesult = 0;
01087 iret = sema_submit_result(smsc, mtrmsg, decoderesult);
01088 if(iret == -1) goto error;
01089 if(iTrcved == 1 &&
01090 report_invoke->status != 3){
01091 info(0,"sema_mt_session: submit invoke failed with report value-%i",report_invoke->status);
01092 gw_free(report_invoke);
01093 goto smsc_say_fail;
01094 }
01095 gw_free(report_invoke);
01096
01097 }
01098 else if(mtrmsg->type == 'M'){
01099
01100
01101 decoderesult = 0;
01102 iret = sema_submit_result(smsc, mtrmsg, decoderesult);
01103 if(iret == -1) goto error;
01104 deliver_invoke = (struct sm_deliver_invoke*) mtrmsg->msgbody;
01105 if(deliver_invoke != NULL){
01106 gw_free(deliver_invoke);
01107
01108 ilen=strlen(mochars);
01109 memcpy(mochars+ilen,data,strlen(data));
01110 ilen=strlen(mochars);
01111 memcpy(mochars+ilen,&ccr,1);
01112 }
01113 time(&tstart);
01114 }
01115
01116 memset(mtrmsg,0,sizeof(struct sema_msg));
01117 }
01118
01119 memset(data,0,sizeof(data));
01120 if(sema_wait_report == 0 && isrcved == 1)
01121 {
01122 info(0,"sema_mt_session: submit invoke delivered successfully to smsc");
01123 goto mo_success;
01124 }
01125 if(sema_wait_report > 0 &&
01126 isrcved == 1 && iTrcved == 1)
01127 {
01128 info(0,"sema_mt_session: submit invoke delivered successfully to msisdn");
01129 goto mo_success;
01130 }
01131 }
01132 }
01133 }
01134
01135
01136 info(0,"sema_mt_session: timeout without receiving all expected returns");
01137 moret = SESSION_MT_RECEIVE_TIMEOUT;
01138 goto mo_return;
01139 mo_success:
01140 moret = SESSION_MT_RECEIVE_SUCCESS;
01141 goto mo_return;
01142 smsc_say_fail:
01143 info(0,"sema_mt_session: smsc says message deliver failed!");
01144 moret = SESSION_MT_RECEIVE_ERR;
01145 goto mo_return;
01146 mo_return:
01147 X28_close_send_link(smsc->sema_fd);
01148
01149
01150 sema_msg_free(mtrmsg);
01151 ilen = strlen(mochars);
01152 i = strlen(smsc->buffer);
01153 if(ilen > 0){
01154 memmove( smsc->buffer+ilen,smsc->buffer,i);
01155 memcpy(smsc->buffer, mochars,ilen);
01156 }
01157 return moret;
01158 sendlink_error:
01159 info(0,"sema_mt_session: X28 data link has broken");
01160 if(mtrmsg != NULL)
01161 sema_msg_free(mtrmsg);
01162 return 0;
01163 encode_error:
01164 info(0,"sema_mt_session: Msg encode error");
01165 return 0;
01166 error:
01167 error(0,"sema_mt session: memory allocation error or device file error");
01168 return -1;
01169
01170 }
01171
01172
01173 static int sema_msg_session_mo(SMSCenter *smsc, char* cbuff){
01174
01175 struct sema_msg *rmsg = NULL;
01176 int iret = 0, retresult = 0;
01177
01178 struct sm_deliver_invoke* deliver_invoke = NULL;
01179 struct sm_statusreport_invoke* report_invoke = NULL;
01180
01181 rmsg = sema_msg_new();
01182
01183 iret = sema_decode_msg(&rmsg,cbuff);
01184 if(iret == - 1) goto msg_error;
01185
01186 if(x28_data_mode == X28_COMMAND_MODE){
01187
01188
01189
01190
01191 X28_close_send_link(smsc->sema_fd);
01192
01193 if(X28_open_send_link(smsc->sema_fd,smsc->sema_smscnua) < 1){
01194 info(0,"sema_mo_session: can not establish send link");
01195 return 0;
01196 }
01197 }
01198
01199 if(rmsg->type == 'M'){
01200 retresult = 0;
01201 iret = sema_submit_result(smsc, rmsg, retresult);
01202 if(iret == -1) goto error;
01203 deliver_invoke = (struct sm_deliver_invoke*) rmsg->msgbody;
01204 if(deliver_invoke == NULL) goto msg_error;
01205 sema_msglist_push(smsc->sema_mo, rmsg);
01206 return 1;
01207 }
01208 else if(rmsg->type == 'T'){
01209 retresult = 0;
01210 sema_submit_result(smsc, rmsg, retresult);
01211 if(iret == -1) goto error;
01212 report_invoke = (struct sm_statusreport_invoke*) rmsg->msgbody;
01213 if(report_invoke != NULL)
01214 gw_free(report_invoke);
01215 }
01216 else{
01217 }
01218 sema_msg_free(rmsg);
01219 return 1;
01220
01221 msg_error:
01222 sema_msg_free(rmsg);
01223 error(0,"sema_mo session: Msg decode failed");
01224 return 0;
01225 error:
01226 error(0,"sema_mo session: device file error or memory allocation problem!");
01227 return -1;
01228 }
01229
01230
01231
01232 static int sema_decode_msg(sema_msg **desmsg, char* octsrc) {
01233 struct sm_deliver_invoke *receive_sm = NULL;
01234 struct sm_statusreport_invoke* receive_report = NULL;
01235 struct sm_submit_result* submit_result = NULL;
01236
01237 unsigned char tmp[1024],tmpgsm[1024];
01238 int octetlen, iret, iusedbyte;
01239 int imsgtopseg = 0, imsgfollownum = 0, imsgencodetype = 0;
01240 unsigned char cmsgtype, cmsgcontinuebyte;
01241
01242
01243 if(strlen(octsrc) <= 4) goto no_msg;
01244
01245
01246 cmsgtype = *octsrc;
01247 if(cmsgtype != 's'
01248 && cmsgtype != 'M'
01249 && cmsgtype != 'T'){
01250 info(0,"sema_decode: msg type not supported");
01251 goto error_msg;
01252 }
01253
01254
01255 cmsgcontinuebyte = *(octsrc+1);
01256 iret = unpack_continous_byte(cmsgcontinuebyte,
01257 &imsgencodetype,&imsgtopseg, &imsgfollownum);
01258
01259 if(iret == -1){
01260 info(0,"sema_decode: msg continue bit can not be interpreted");
01261 goto error_msg;
01262 }
01263
01264
01265
01266
01267
01268 if(imsgtopseg == 0){
01269 info(0, "sema_decode: can not interpret more than one segments msg");
01270 goto error_msg;
01271 }
01272
01273 (*desmsg)->type = cmsgtype;
01274 (*desmsg)->continuebyte = cmsgcontinuebyte;
01275 (*desmsg)->encodetype = imsgencodetype;
01276
01277
01278
01279 memcpy((*desmsg)->optref, octsrc +2, 4);
01280 octsrc += 6;
01281 iusedbyte = 0;
01282
01283 switch(cmsgtype){
01284 case 's':
01285 submit_result = gw_malloc(sizeof(struct sm_submit_result));
01286 memset(submit_result,0,sizeof(struct sm_submit_result));
01287
01288
01289 iusedbyte = line_scan_IA5_hex(octsrc, 1, tmp);
01290 if(iusedbyte < 1) goto error_submit;
01291 octetlen = 1;
01292 submit_result->smeresult = get_variable_value(tmp, &octetlen);
01293 if(submit_result->smeresult == SM_RESULT_SUCCESS)
01294 {
01295
01296 octsrc += iusedbyte;
01297 iusedbyte = line_scan_IA5_hex(octsrc, 4,tmp);
01298 if(iusedbyte <1) goto error_submit;
01299 memcpy(submit_result->smscrefnum, tmp, 4);
01300
01301 octsrc += iusedbyte;
01302 iusedbyte = line_scan_IA5_hex(octsrc, 14,tmp);
01303 if(iusedbyte < 1) goto error_submit;
01304 memcpy(submit_result->accepttime, tmp, 4);
01305 }
01306 (*desmsg)->msgbody = submit_result;
01307 break;
01308 case 'M':
01309
01310 receive_sm = gw_malloc(sizeof(struct sm_deliver_invoke));
01311 memset(receive_sm, 0, sizeof(struct sm_deliver_invoke));
01312
01313 iusedbyte = line_scan_IA5_hex(octsrc, 1, tmp);
01314 if(iusedbyte < 1) goto error_deliver;
01315 octetlen = 1;
01316 receive_sm->destaddlen = get_variable_value(tmp, &octetlen);
01317
01318 octsrc +=iusedbyte;
01319 iusedbyte = line_scan_IA5_hex(octsrc,receive_sm->destaddlen,tmp);
01320 if(iusedbyte < 1) goto error_deliver;
01321 receive_sm->destadd= octstr_create_from_data((char *)tmp, receive_sm->destaddlen);
01322
01323 octsrc +=iusedbyte;
01324 iusedbyte = line_scan_IA5_hex(octsrc, 4,tmp);
01325 if(iusedbyte < 1) goto error_deliver;
01326 memcpy(receive_sm->smscrefnum, tmp, 4);
01327
01328 octsrc +=iusedbyte;
01329 iusedbyte = line_scan_IA5_hex(octsrc, 1, tmp);
01330 if(iusedbyte < 1) goto error_deliver;
01331 octetlen = 1;
01332 receive_sm->origaddlen = get_variable_value(tmp, &octetlen);
01333
01334 octsrc +=iusedbyte;
01335 iusedbyte = line_scan_IA5_hex(octsrc, receive_sm->origaddlen, tmp);
01336 if(iusedbyte < 1) goto error_deliver;
01337 receive_sm->origadd= octstr_create_from_data((char *)tmp,receive_sm->origaddlen);
01338
01339 octsrc +=iusedbyte;
01340 if(iusedbyte < 1) goto error_deliver;
01341 iusedbyte = line_scan_IA5_hex(octsrc, 1,tmp);
01342 octetlen = 1;
01343 receive_sm->DCS = get_variable_value(tmp, &octetlen);
01344 if(receive_sm->DCS != ENCODE_IA5 && receive_sm->DCS !=ENCODE_GSM){
01345 info(0, "sema_decode, Data encoding scheme not supported");
01346 goto error_deliver;
01347 }
01348
01349 octsrc +=iusedbyte;
01350 iusedbyte = line_scan_IA5_hex(octsrc, 1,tmp);
01351 if(iusedbyte < 1) goto error_deliver;
01352 octetlen = 1;
01353 receive_sm->protocal = get_variable_value(tmp, &octetlen);
01354
01355 octsrc +=iusedbyte;
01356 iusedbyte = line_scan_IA5_hex(octsrc, 1,tmp);
01357 if(iusedbyte < 1) goto error_deliver;
01358 octetlen = 1;
01359 receive_sm->replypath = get_variable_value(tmp, &octetlen);
01360
01361 octsrc +=iusedbyte;
01362 iusedbyte = internal_char_IA5_to_hex(octsrc, tmp);
01363 if(iusedbyte < 1) goto error_deliver;
01364 receive_sm->textsizeseptet = tmp[0];
01365
01366 octsrc +=iusedbyte;
01367 iusedbyte = internal_char_IA5_to_hex(octsrc, tmp);
01368 if(iusedbyte < 1) goto error_deliver;
01369 receive_sm->textsizeoctect = tmp[0];
01370 octsrc+=iusedbyte;
01371
01372
01373
01374 iusedbyte = 0;
01375 memset(tmp,0,sizeof(tmp));
01376 if(receive_sm->DCS == ENCODE_IA5 && receive_sm->textsizeoctect > 0)
01377 {
01378 iusedbyte = line_scan_IA5_hex(octsrc,receive_sm->textsizeoctect,tmp);
01379 if(iusedbyte < 1) goto error_deliver;
01380 receive_sm->shortmsg =octstr_create_from_data( (char *)tmp,receive_sm->textsizeoctect);
01381 }
01382 else if(receive_sm->DCS == ENCODE_GSM && receive_sm->textsizeseptet > 0)
01383 {
01384 memset(tmpgsm,0,sizeof(tmpgsm));
01385
01386 iusedbyte = line_scan_IA5_hex(octsrc,receive_sm->textsizeoctect,tmp);
01387 if(iusedbyte < 1) goto error_deliver;
01388 line_scan_hex_GSM7(tmp,receive_sm->textsizeoctect,
01389 receive_sm->textsizeseptet, tmpgsm);
01390 receive_sm->shortmsg = octstr_create_from_data((char *)tmpgsm,
01391 receive_sm->textsizeseptet);
01392
01393 }
01394 else if(receive_sm->textsizeoctect <= 0)
01395 receive_sm->shortmsg = octstr_create("");
01396
01397
01398 octsrc +=iusedbyte;
01399 iusedbyte = line_scan_IA5_hex(octsrc,14,tmp);
01400 if(iusedbyte < 1) goto error_deliver;
01401 memcpy(receive_sm->accepttime, tmp,14);
01402
01403 octsrc +=iusedbyte;
01404 iusedbyte = line_scan_IA5_hex(octsrc,14,tmp);
01405 if(iusedbyte < 1) goto error_deliver;
01406 memcpy(receive_sm->invoketime, tmp,14);
01407 (*desmsg)->msgbody = receive_sm;
01408 break;
01409 case 'T':
01410
01411 receive_report = gw_malloc(sizeof(struct sm_statusreport_invoke));
01412 memset(receive_report,0,sizeof(struct sm_statusreport_invoke));
01413
01414 iusedbyte = line_scan_IA5_hex(octsrc, 1, tmp);
01415 if(iusedbyte < 1) goto error_receive;
01416 octetlen = 1;
01417 receive_report->msisdnlen = get_variable_value(tmp, &octetlen);
01418
01419 octsrc += iusedbyte;
01420 iusedbyte = line_scan_IA5_hex(octsrc, receive_report->msisdnlen, tmp);
01421 if(iusedbyte < 1) goto error_receive;
01422 receive_report->msisdn = octstr_create_from_data( (char *)tmp,receive_report->msisdnlen);
01423
01424 octsrc += iusedbyte;
01425 iusedbyte = line_scan_IA5_hex(octsrc, 1, tmp);
01426 if(iusedbyte < 1) goto error_receive;
01427 octetlen = 1;
01428 receive_report->smetype = get_variable_value(tmp, &octetlen);
01429
01430 octsrc += iusedbyte;
01431 iusedbyte = line_scan_IA5_hex(octsrc,4, tmp);
01432 if(iusedbyte < 1) goto error_receive;
01433 memcpy(receive_report->smerefnum ,tmp, 4);
01434
01435 octsrc += iusedbyte;
01436 iusedbyte = line_scan_IA5_hex(octsrc,4, tmp);
01437 if(iusedbyte < 1) goto error_receive;
01438 memcpy(receive_report->smscrefnum ,tmp, 4);
01439
01440 octsrc += iusedbyte;
01441 iusedbyte = line_scan_IA5_hex(octsrc,14, tmp);
01442 if(iusedbyte < 1) goto error_receive;
01443 memcpy(receive_report->accepttime ,tmp, 4);
01444
01445 octsrc += iusedbyte;
01446 iusedbyte = line_scan_IA5_hex(octsrc, 1, tmp);
01447 if(iusedbyte < 1) goto error_receive;
01448 octetlen = 1;
01449 receive_report->status = get_variable_value(tmp, &octetlen);
01450 octsrc += iusedbyte;
01451 if(receive_report->status != 6)
01452 {
01453 iusedbyte = line_scan_IA5_hex(octsrc,14, tmp);
01454 if(iusedbyte < 1) goto error_receive;
01455 memcpy(receive_report->completetime ,tmp, 14);
01456 }
01457 else
01458 {
01459 iusedbyte = line_scan_IA5_hex(octsrc,14, tmp);
01460 if(iusedbyte < 1) goto error_receive;
01461 memcpy(receive_report->intermediatime ,tmp, 14);
01462 }
01463 if(receive_report->status == 6 || receive_report->status == 1)
01464 {
01465 octsrc += iusedbyte;
01466 iusedbyte = line_scan_IA5_hex(octsrc, 1, tmp);
01467 if(iusedbyte < 1) goto error_receive;
01468 octetlen = 1;
01469 receive_report->failreason = get_variable_value(tmp, &octetlen);
01470 }
01471
01472 octsrc += iusedbyte;
01473 iusedbyte = line_scan_IA5_hex(octsrc, 1, tmp);
01474 if(iusedbyte < 1) goto error_receive;
01475 octetlen = 1;
01476 receive_report->origaddlen = get_variable_value(tmp, &octetlen);
01477
01478 octsrc += iusedbyte;
01479 iusedbyte = line_scan_IA5_hex(octsrc, receive_report->origaddlen, tmp);
01480 if(iusedbyte < 1) goto error_receive;
01481 receive_report->origadd = octstr_create_from_data((char *)tmp, receive_report->msisdnlen);
01482
01483 octsrc += iusedbyte;
01484 iusedbyte = line_scan_IA5_hex(octsrc,14, tmp);
01485 if(iusedbyte < 1){
01486 goto error_receive;
01487 }
01488 memcpy(receive_report->invoketime ,tmp, 14);
01489 (*desmsg)->msgbody = receive_report;
01490 break;
01491 }
01492 return 1;
01493
01494 no_msg:
01495 info(0,"sema_decode: msg is empty");
01496 return 0;
01497 error_receive:
01498 gw_free(receive_report);
01499 goto error_msg;
01500 error_submit:
01501 gw_free(submit_result);
01502 goto error_msg;
01503 error_deliver:
01504 gw_free(receive_sm);
01505 goto error_msg;
01506 error_msg:
01507 info(0,"sema_decode:msg parameter is not recognized or unsupported");
01508 return 0;
01509 }
01510
01511
01512 static int sema_encode_msg(sema_msg* pmsg, char* str) {
01513 struct sm_submit_invoke *submit_sm = NULL;
01514 Octstr *IA5msg = NULL;
01515 int tSize = 0;
01516 unsigned char oc1byte[10];
01517 IA5msg = octstr_create("");
01518 switch(pmsg->type)
01519 {
01520 case 'S':
01521 submit_sm = (struct sm_submit_invoke *) pmsg->msgbody;
01522 write_variable_value(submit_sm->msisdnlen, oc1byte);
01523 line_append_hex_IA5(IA5msg, oc1byte,1);
01524 line_append_hex_IA5(IA5msg,
01525 (unsigned char *)octstr_get_cstr(submit_sm->msisdn),
01526 octstr_len(submit_sm->msisdn));
01527 write_variable_value(submit_sm->smereftype, oc1byte);
01528 line_append_hex_IA5(IA5msg, oc1byte,1);
01529 line_append_hex_IA5(IA5msg, submit_sm->smerefnum,4);
01530 write_variable_value(submit_sm->priority, oc1byte);
01531 line_append_hex_IA5(IA5msg, oc1byte,1);
01532 write_variable_value(submit_sm->origaddlen, oc1byte);
01533 line_append_hex_IA5(IA5msg, oc1byte,1);
01534 line_append_hex_IA5(IA5msg,
01535 (unsigned char *)octstr_get_cstr(submit_sm->origadd),
01536 octstr_len(submit_sm->origadd));
01537 write_variable_value(submit_sm->validperiodtype, oc1byte);
01538 line_append_hex_IA5(IA5msg, oc1byte,1);
01539 write_variable_value(submit_sm->validperiodrela, oc1byte);
01540 line_append_hex_IA5(IA5msg, oc1byte,1);
01541 write_variable_value(submit_sm->DCS, oc1byte);
01542 line_append_hex_IA5(IA5msg, oc1byte,1);
01543 write_variable_value(submit_sm->statusreportrequest, oc1byte);
01544 line_append_hex_IA5(IA5msg, oc1byte,1);
01545 write_variable_value(submit_sm->protocal, oc1byte);
01546 line_append_hex_IA5(IA5msg, oc1byte, 1);
01547 write_variable_value(submit_sm->replypath, oc1byte);
01548 line_append_hex_IA5(IA5msg, oc1byte, 1);
01549
01550
01551 tSize = internal_char_hex_to_IA5(submit_sm->textsizeseptet,oc1byte);
01552 octstr_insert_data(IA5msg, octstr_len(IA5msg), (char *)oc1byte, tSize);
01553
01554
01555 tSize = internal_char_hex_to_IA5(submit_sm->textsizeoctect,oc1byte);
01556 octstr_insert_data(IA5msg, octstr_len(IA5msg),(char *) oc1byte, tSize);
01557
01558 line_append_hex_IA5(IA5msg,
01559 (unsigned char *)octstr_get_cstr(submit_sm->shortmsg),
01560 submit_sm->textsizeoctect);
01561 memcpy(str,octstr_get_cstr(IA5msg),octstr_len(IA5msg));
01562 octstr_destroy(IA5msg);
01563 return 1;
01564 }
01565 return 0;
01566 }
01567
01568
01569 static int line_scan_hex_GSM7(unsigned char* from,
01570 int octects ,int spetets, unsigned char* to)
01571 {
01572 char* cin2 =NULL;
01573 unsigned char c;
01574 char cin7[8];
01575 int i, pos, value;
01576
01577 int lenin2=octects*8;
01578 cin2 = gw_malloc(lenin2);
01579
01580 memset(cin2,48,lenin2);
01581
01582 for(i = 0; i < octects; i ++)
01583 {
01584 c = *(from + i);
01585
01586 if(c & 1)
01587 cin2[(octects-1-i)*8 +7] = 49;
01588 if(c & 2)
01589 cin2[(octects-1-i)*8 +6] = 49;
01590 if(c & 4)
01591 cin2[(octects-1-i)*8 +5] = 49;
01592 if(c & 8)
01593 cin2[(octects-1-i)*8 +4] = 49;
01594 if(c & 16)
01595 cin2[(octects-1-i)*8 +3] = 49;
01596 if(c & 32)
01597 cin2[(octects-1-i)*8 +2] = 49;
01598 if(c & 64)
01599 cin2[(octects-1-i)*8 +1] = 49;
01600 if(c & 128)
01601 cin2[(octects-1-i)*8] = 49;
01602 }
01603
01604 i= 1;
01605 while( i <= spetets ){
01606 pos=lenin2 -1 -(i*7 -1);
01607 memset(cin7,0,sizeof(cin7));
01608 memcpy(cin7, cin2 + pos, 7);
01609 value = 0;
01610
01611 if(cin7[6] == '1')
01612 value += 1;
01613 if(cin7[5] == '1')
01614 value += 2;
01615 if(cin7[4] == '1')
01616 value += 4;
01617 if(cin7[3] == '1')
01618 value += 8;
01619 if(cin7[2] == '1')
01620 value += 16;
01621 if(cin7[1] == '1')
01622 value += 32;
01623 if(cin7[0] == '1')
01624 value += 64;
01625
01626 to[i-1]=internal_char_hex_to_gsm(value);
01627 i +=1;
01628 }
01629 return i;
01630
01631 }
01632
01633
01634 static int line_append_hex_IA5(Octstr* des, unsigned char* src, int len)
01635 {
01636
01637 unsigned char IA5char[3];
01638 unsigned char tmp[1024];
01639 int j=0;
01640 int i=0, iall=0;
01641 for(i=0; i<len; i++)
01642 {
01643 memset(IA5char, 0, sizeof(IA5char));
01644 j=internal_char_hex_to_IA5(*(src+i),IA5char);
01645 if(j >0){
01646 memcpy(tmp+iall,IA5char,j);
01647 iall += j;
01648 }
01649 }
01650 octstr_insert_data(des,octstr_len(des),(char *)tmp,iall);
01651 return iall;
01652 }
01653
01654
01655
01656 static int line_scan_IA5_hex(char* from,
01657 int hexnum, unsigned char* to)
01658 {
01659 unsigned char cha[1];
01660 int cn =0, cnall = 0, i = 0;
01661 char *tmpfrom = NULL;
01662 tmpfrom = from;
01663 for(i = 0; i< hexnum; i++)
01664 {
01665 cn=internal_char_IA5_to_hex(tmpfrom, cha);
01666 if(cn >0)
01667 {
01668 memcpy(to+i,cha,1);
01669 tmpfrom += cn;
01670 cnall += cn;
01671 }
01672 else
01673 return -1;
01674 }
01675 return cnall;
01676 }
01677
01678
01679 static unsigned char internal_char_hex_to_gsm(unsigned char from)
01680 {
01681 switch (from){
01682 case 0x00: return '@';
01683 case 0x01: return '£';
01684 case 0x02: return '$';
01685 case 0x03: return '¥';
01686 case 0x04: return 'è';
01687 case 0x05: return 'é';
01688 case 0x06: return 'ù';
01689 case 0x07: return 'ì';
01690 case 0x08: return 'ò';
01691 case 0x09: return 'Ç';
01692 case 0x0A: return '\n';
01693 case 0x0B: return 'Ø';
01694 case 0x0C: return 'ø';
01695 case 0x0D: return '\r';
01696 case 0x0E: return 'Å';
01697 case 0x0F: return 'å';
01698 case 0x10: return 'D';
01699 case 0x11: return ' ';
01700 case 0x12: return 'F';
01701 case 0x13: return 'G';
01702 case 0x14: return 'L';
01703 case 0x15: return 'W';
01704 case 0x16: return 'P';
01705 case 0x17: return 'Y';
01706 case 0x18: return 'S';
01707 case 0x19: return 'Q';
01708 case 0x1A: return 'X';
01709 case 0x1B: return ' ';
01710 case 0x1C: return 'Æ';
01711 case 0x1D: return 'æ';
01712 case 0x1E: return 'b';
01713 case 0x1F: return 'É';
01714 case 0x5B: return 'Ä';
01715 case 0x5C: return 'Ö';
01716 case 0x5D: return 'Ñ';
01717 case 0x5E: return 'Ü';
01718 case 0x5F: return '§';
01719 case 0x60: return '¿';
01720 case 0x7B: return 'a';
01721 case 0x7C: return 'ö';
01722 case 0x7D: return 'ñ';
01723 case 0x7E: return 'ü';
01724 case 0x7F: return 'à';
01725 default: return from;
01726 }
01727 }
01728
01729
01730 static int internal_char_hex_to_IA5(unsigned char from, unsigned char * to){
01731
01732 if(from <= 0x1F)
01733 {
01734 to[0] = '^';
01735 to[1] = 0x40 + from;
01736 return 2;
01737 }
01738 else if(from ==0x5C)
01739 {
01740 to[0] = 0x5C;
01741 to[1] = 0x5C;
01742 return 2;
01743 }
01744 else if(from == 0x5E)
01745 {
01746 to[0] = 0x5C;
01747 to[1] = 0x5E;
01748 return 2;
01749 }
01750 else if(from == 0x60)
01751 {
01752 to[0] = 0x5C;
01753 to[1] = 0x60;
01754 return 2;
01755 }
01756 else if(from == 0x7E)
01757 {
01758 to[0] = 0x5C;
01759 to[1] = 0x7E;
01760 return 2;
01761 }
01762 else if(from >= 0x20 && from <= 0x7E)
01763 {
01764 to [0] = from;
01765 return 1;
01766 }
01767 else if(from == 0x7F)
01768 {
01769 to[0] = 0x5E;
01770 to[1] = 0x7E;
01771 return 2;
01772 }
01773 else if(from >= 0x80 && from <=0x9F)
01774 {
01775 to[0] = 0x7E;
01776 to[1] = from -0x40;
01777 return 2;
01778 }
01779 else if(from >= 0xA0 && from <=0xFE)
01780 {
01781 to[0] = 0x60;
01782 to[1] = from -0x80;
01783 return 2;
01784 }
01785 else if(from == 0xFF)
01786 {
01787 to[0] =to[1] = 0x7E;
01788 return 2;
01789 }
01790 else
01791
01792 return -1;
01793 }
01794
01795 static int internal_char_IA5_to_hex(char *from, unsigned char * to){
01796 int ret = -1;
01797 int len = strlen(from);
01798
01799 if(*from == '^' && len >= 2 &&
01800 *(from +1) == '~')
01801 {
01802 *to = 0x7F;
01803 ret = 2;
01804 }
01805 else if(*from ==0x5C && len >= 2 &&
01806 *(from +1) == 0x5C)
01807 {
01808 *to= 0x5C;
01809 ret = 2;
01810 }
01811 else if(*from == 0x5C && len >= 2 &&
01812 *(from+1) == 0x5E)
01813 {
01814 *to= 0x5E;
01815 ret = 2;
01816 }
01817 else if(*from == 0x5C && len >= 2 &&
01818 *(from+1) == 0x60)
01819 {
01820 *to= 0x60;
01821 ret = 2;
01822 }
01823 else if(*from == 0x5C && len >=2 &&
01824 *(from+1) == 0x7E)
01825 {
01826 *to= 0x7E;
01827 ret = 2;
01828 }
01829 else if(*from == '^' && len >= 2 &&
01830 (*(from +1) >= 0x40 && *(from +1) <= 0x5F))
01831 {
01832 *to = *(from +1) -0x40;
01833 ret = 2;
01834 }
01835 else if(*from == '~' && len >= 2 &&
01836 (*(from +1) >= 0x40 && *(from +1) <= 0x5F))
01837 {
01838 *to = *(from +1) +0x40;
01839 ret = 2;
01840 }
01841 else if(*from == '`' && len >= 2 &&
01842 (*(from+1) >= 0x20 && *(from +1) <= 0x7E))
01843 {
01844 *to = *(from +1) +0x80;
01845 ret = 2;
01846 }
01847 else if(*from >=0x20 &&
01848 *from <=0x7E)
01849 {
01850 *to= *from;
01851 ret = 1;
01852 }
01853
01854 return ret;
01855 }
01856
01857
01858 static void increment_counter(void)
01859 {
01860 if(sema_counter[3] == 0x39)
01861 sema_counter[3] = 0x30;
01862 else
01863 {
01864 sema_counter[3] += 0x01;
01865 return;
01866 }
01867 if(sema_counter[2] == 0x39)
01868 sema_counter[2] = 0x30;
01869 else
01870 {
01871 sema_counter[2] += 0x01;
01872 return;
01873 }
01874 if(sema_counter[1] == 0x39)
01875 sema_counter[1] = 0x30;
01876 else
01877 {
01878 sema_counter[1] += 0x01;
01879 return;
01880 }
01881 if(sema_counter[0] == 0x39)
01882 sema_counter[0] = 0x30;
01883 else
01884 sema_counter[0] += 0x01;
01885 return;
01886 }
01887
01888
01889 static unsigned char pack_continous_byte(int encode,
01890 int isfirst, int follownum)
01891 {
01892 char bin[4];
01893 int value;
01894
01895 memset(bin, 0, 4);
01896 value = 0;
01897
01898 if(isfirst == 1)
01899 strncpy(bin,"0101",4);
01900 else
01901 strncpy(bin,"0110",4);
01902
01903 if(bin[3] == '1')
01904 value += 16;
01905 if(bin[2] == '1')
01906 value += 32;
01907 if(bin[1] == '1')
01908 value += 64;
01909 if(bin[0] == '1')
01910 value += 128;
01911 return (value+follownum);
01912 }
01913
01914
01915 static int unpack_continous_byte(unsigned char continueCount,
01916 int * encode,
01917 int * isfirst,
01918 int * follownum)
01919 {
01920 int rest = 0;
01921 int head = 0;
01922
01923 if(continueCount & 1)
01924 rest +=1;
01925 if(continueCount & 2)
01926 rest +=2;
01927 if(continueCount & 4)
01928 rest += 4;
01929 if(continueCount & 8)
01930 rest += 8;
01931
01932 *follownum = rest;
01933
01934 if(continueCount & 16)
01935 head += 1;
01936
01937 if(continueCount & 32)
01938 head += 2;
01939
01940 if(continueCount & 64)
01941 head += 4;
01942
01943 if(continueCount & 128)
01944 head += 8;
01945
01946
01947 *encode = *isfirst = -1;
01948
01949 if(head == 5)
01950 {
01951 *encode =LINE_ENCODE_IA5;
01952 *isfirst = 1;
01953 }
01954 else if(head == 6)
01955 {
01956 *encode =LINE_ENCODE_IA5;
01957 *isfirst = 0;
01958 }
01959 else if(head == 4)
01960 {
01961 *encode =LINE_ENCODE_HEX;
01962 *isfirst = 1;
01963 }
01964 else if(head == 3)
01965 {
01966 *encode =LINE_ENCODE_HEX;
01967 *isfirst = 0;
01968 }
01969 else if(head == 7)
01970 {
01971 *encode =LINE_ENCODE_BIN;
01972 *isfirst = 1;
01973 }
01974 else if(head == 2)
01975 {
01976 *encode =LINE_ENCODE_BIN;
01977 *isfirst = 0;
01978 }
01979 if(*encode != -1 && *isfirst != -1)
01980 return 0;
01981 else
01982 return -1;
01983 }
01984
See file LICENSE for details about the license agreement for using,
modifying, copying or deriving work from this software.