?? smsc_sema.c
字號:
static int sema_msg_free(sema_msg *msg) { if(msg == NULL) return 0; gw_free(msg); return 1;}static sema_msglist* sema_msglist_new(void) { struct sema_msglist *mlist = NULL; mlist = gw_malloc(sizeof(struct sema_msglist)); memset(mlist, 0, sizeof(struct sema_msglist)); mlist->first = NULL; mlist->last = NULL; mlist->count = 0; return mlist;}static void sema_msglist_free(sema_msglist *mlist) { struct sema_msg *pmsg = NULL; if(mlist == NULL) return; while( sema_msglist_pop(mlist, &pmsg) == 1 ) { if(pmsg==NULL) break; sema_msg_free(pmsg); pmsg = NULL; } gw_free(mlist); mlist->count = 0;}static int sema_msglist_push(sema_msglist *plist, sema_msg *pmsg) { struct sema_msg * lmsg = NULL; if(plist == NULL) { info(0, "msglist_push: NULL msg list"); goto error; } if(pmsg == NULL) { info(0, "msglist_push: NULL input"); goto error; } /* If list is completely empty. */ if( plist->first == NULL ) { plist->last = pmsg; plist->first = pmsg; pmsg->prev = NULL; pmsg->next = NULL; } else{ lmsg=plist->last; lmsg->next=pmsg; pmsg->prev=lmsg; pmsg->next=NULL; plist->last=pmsg; } plist->count += 1; return 1;error: error(0, "msglist_push: error"); return 0;}static int sema_msglist_pop(sema_msglist *plist, sema_msg **msg) { if(plist == NULL) { info(0, "msglist_pop: NULL list"); goto no_msg; } if(plist->first == NULL) { goto no_msg; } *msg = plist->first; if(plist->last == *msg) { plist->first = NULL; (*msg)->prev = NULL; plist->last = NULL; } else { plist->first = (*msg)->next; plist->first->prev = NULL; if(plist->first->next == NULL) plist->last = plist->first; } plist->count -= 1; return 1;no_msg: return 0;}static int X28_open_data_link(char* device){ int fd = -1, iret; struct termios tios; info(0,"open serial device %s",device); fd = open(device, O_RDWR|O_NONBLOCK|O_NOCTTY); if(fd==-1) { error(errno, "sema_open_data_link: error open(2)ing the character device <%s>", device); if(errno == EACCES) error(0, "sema_open_data_link: user has no right to access the serial device"); return -1; } tcgetattr(fd, &tios); cfsetospeed(&tios, B4800); /* check radio pad parameter*/ cfsetispeed(&tios, B4800); kannel_cfmakeraw(&tios); tios.c_iflag |= IGNBRK|IGNPAR|INPCK|ISTRIP; tios.c_cflag |= (CSIZE|HUPCL | CREAD | CRTSCTS); tios.c_cflag ^= PARODD; tios.c_cflag |=CS7; iret = tcsetattr(fd, TCSANOW, &tios); if(iret == -1){ error(errno,"sema_open_data_link: fail to set termios attribute"); goto error; } tcflush(fd, TCIOFLUSH); return fd; error: return -1;}static int X28_reopen_data_link(int oldpadfd ,char* device){ int nret = 0; if(oldpadfd > 0){ nret= close(oldpadfd); if(nret == -1){ error(errno,"sema_reopen_data_link: close device file failed!!"); } } sleep(1); return X28_open_data_link(device);} static int X28_close_send_link(int padfd){ unsigned char discnntbuff[5]; unsigned char readbuff[1024]; unsigned char finishconfirm[]="CLR CONF\0"; int nret = 0, readall = 0; time_t tstart; time(&tstart); sprintf(discnntbuff,"%cCLR\r",0x10); memset(readbuff,0,sizeof(readbuff)); /* what ever is the close return, data mode is unreliable now*/ x28_data_mode = X28_COMMAND_MODE; if(padfd <= 0) goto datalink_error; while((time(NULL) - tstart) < INTERNAL_DISCONNECT_TIMEVAL){ nret =write(padfd, discnntbuff, 5); if(nret == -1){ if(errno == EAGAIN || errno ==EINTR) continue; else{ goto datalink_error; } } sleep(1); /*wait 1 senconds for virtual link break*/ nret=read(padfd, readbuff+readall,128); if(nret == -1){ if(errno == EAGAIN || errno ==EINTR) continue; else{ goto datalink_error; } } if(nret >0){ readall += nret; if(strstr(readbuff,finishconfirm)) 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(×tart); 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 responded, virtual link established"); x28_data_mode = X28_MT_DATA_MODE; return 1; } } usleep(1000); } info(0,"sema_open_send_link: connect timeout"); 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 error"); 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); }
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -