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

📄 smspdu.c

📁 pc 透過simens mobile phone 連線,可直接傳訊.
💻 C
📖 第 1 页 / 共 2 页
字号:
/*************************************************************************** *   copyright           : (C) 2002 by Hendrik Sattler                     * *   mail                : post@hendrik-sattler.de                         * *                                                                         * *   This program is free software; you can redistribute it and/or modify  * *   it under the terms of the GNU General Public License as published by  * *   the Free Software Foundation; either version 2 of the License, or     * *   (at your option) any later version.                                   * *                                                                         * ***************************************************************************/#include "common.h"#include "charsets.h"#include "helpers.h"#include "smscoding.h"#include "depincludes.h"#include "smspdu.h"#include <stdlib.h>#include <string.h>void create_smssubmit_pdu(char *pdu, char* smstext, char* smsnumber, struct smsopts mysmsopts){	  sms_number_t sca; //SMSC  unsigned int pdutype; //8bits, convert to hex-string, use defined values!  unsigned int mr=0; //message reference, DO NOT CHANGE!!! SET BY THE PHONE!, convert to hex-string  sms_number_t da; //destination  unsigned int pid=0; //protocol identifier, normally 0, convert to hex-string  unsigned int dcs; //data coding scheme, convert to hex-string  unsigned int vp_relative=255; //validity period (0-255, set to max=63 weeks), convert to hex-string  unsigned char vp_absolute[15]; //validity period (YYMMDDhhmmss(TZ))  unsigned int udl; //user data length, convert to hex-string  unsigned char* ud;			  char buffer,temp[17];  int i;  wchar_t* wide_str;	  memset(sca.number,0,sizeof(sca.number));  memset(da.number,0,sizeof(da.number));  memset(vp_absolute,0,sizeof(vp_absolute));  memset(temp,0,sizeof(temp));	  //set SMSC length to 0 to let the phone fill it in  sca.length=0;  //we do not have to set the rest of sca	  //set PDU type to standards (if you change it, make sure you know what you are doing!!!)  //those are bits!  pdutype = 1 | (1<<4);  if (mysmsopts.srr) {    pdutype |= (1<<5);  }  //leave message reference as is	  //process destination  if (!strlen(smsnumber)){    errexit("Error: no SMS number specified.\n");  }  strcpy(da.number,smsnumber);  //check the numver  if (!is_pnumber(smsnumber,1)) {    errexit("Hey, no poking around with bogus SMS numbers, please.\n");  }  buffer=smsnumber[0];  if(buffer=='+'){    da.type=145;    da.length=strlen(da.number)-1;    if ((strlen(da.number)%2)==0) {      sprintf(&da.number[strlen(da.number)],"F");    }    for(i=1;i<(strlen(da.number)-1);i=i+2){      sprintf(&temp[strlen(temp)],"%c%c",da.number[i+1],da.number[i]);    }		  }else{    da.type=129;    da.length=strlen(da.number);    if ((strlen(da.number)%2)==1) {      sprintf(&da.number[strlen(da.number)],"F");    }    for(i=0;i<(strlen(da.number)-1);i=i+2){      sprintf(&temp[strlen(temp)],"%c%c",da.number[i+1],da.number[i]);    }		  }  strcpy(da.number,temp);	  dcs=0;  //differ between normal and flash-sms  if (mysmsopts.flash) {    dcs &= 0xec; //clear all affected bits    dcs |= 0x10; //set class 0 message (immediate display)  }  //leave PID and vp_relative as is	  //process user data length and user data  wide_str=convert_to_internal(nl_langinfo(CODESET),smstext,strlen(smstext));  if (mysmsopts.unicode) {    dcs &= 0xf3; //clear all affected bits    dcs |= 0x08; //set unicode charset    ud=convert_to_ucs2(wide_str);    udl=strlen(ud)/2;    //check user data content length    if (udl/2 > MAXSMSSIZEUCS) {      errexit ("SMS text is too long (max. %d characters).\n", MAXSMSSIZEUCS);    }  } else {    ud=sms_data_7bit_encode(wide_str,&udl);  }  mem_realloc(wide_str,0);	  //create PDU  memset(pdu,0,sizeof(pdu));  sprintf(&pdu[strlen(pdu)],"%02X",sca.length);  sprintf(&pdu[strlen(pdu)],"%02X",pdutype);  sprintf(&pdu[strlen(pdu)],"%02X",mr);	  sprintf(&pdu[strlen(pdu)],"%02X%02X%s",da.length,da.type,da.number);  sprintf(&pdu[strlen(pdu)],"%02X",pid);  sprintf(&pdu[strlen(pdu)],"%02X",dcs);  sprintf(&pdu[strlen(pdu)],"%02X",vp_relative);  sprintf(&pdu[strlen(pdu)],"%02X%s",udl,ud);  mem_realloc(ud,0);}void decode_smsdeliver_pdu(unsigned char* pdu, int status){  //this is much more complicated because we have to handle ALL sms types!!!  //right now, this only includes type SMS-DELIVER, SMS_SUBMIT  sms_number_t sca; //SMSC  unsigned int pdutype;  sms_number_t oa;  unsigned int pid=0;  unsigned int dcs=0;  unsigned char scts[91];  unsigned int udl;  unsigned char ud[281];  unsigned int udh_length=0;  unsigned char udh[BUFSIZ];	  unsigned char temp[281];  unsigned char result[BUFSIZ];  int i, where=0;  unsigned char* t;  wchar_t* wide_str;  struct tm sctime;	  memset(temp,0,sizeof(temp));  memset(result,0,sizeof(result));  memset(sca.number,0,sizeof(sca.number));  memset(oa.number,0,sizeof(oa.number));  memset(scts,0,sizeof(scts));  memset(ud,0,sizeof(ud));  memset(udh,0,sizeof(udh));  memset(&sctime,0,sizeof(sctime));	  //extracting SMSC	  sca.length=hexstr2int(pdu+where,2);  where+=2;  if (sca.length){    sca.type=hexstr2int(pdu+where,2);    if ((sca.type&112)==16){sprintf(sca.number,"+");}    where+=sca.length*2;    for (i=4;i<where;i+=2) {      sprintf(&sca.number[strlen(sca.number)],"%c%c",pdu[i+1],pdu[i]);    }    if (!strcmp(&sca.number[strlen(sca.number)-1],"F")) {      memset(&sca.number[strlen(sca.number)-1],0,1);    }  }	  //checking all type bits  pdutype=hexstr2int(pdu+where,2);  where+=2;	  //checking if PDUtype is supported and can thus be decoded  if (status==0 || status==1) {    switch(pdutype&3) {    case SMS_DELIVER:      break;    case SMS_SUBMIT_REPORT:      myprintf(0,"Unsupported pdu type: %s\n","SMS-SUBMIT-REPORT");      memset(pdu,0,sizeof(pdu));      return;      break;    case SMS_STATUS_REPORT:      myprintf(0,"Unsupported pdu type: %s\n","SMS-STATUS-REPORT");      memset(pdu,0,sizeof(pdu));      return;      break;    default:      myprintf(0,"Unknown pdu type.\n");      memset(pdu,0,sizeof(pdu));      return;      break;    }  } else if (status==2 || status==3) {    switch(pdutype&3) {    case SMS_DELIVER_REPORT:      myprintf(0,"Unsupported pdu type: %s\n","SMS-DELIVER-REPORT");      memset(pdu,0,sizeof(pdu));      return;      break;    case SMS_SUBMIT:      where+=2; //MR value      break;    case SMS_COMMAND:      myprintf(0,"Unsupported pdu type: %s\n","SMS-COMMAND");      memset(pdu,0,sizeof(pdu));      return;      break;    default:      myprintf(0,"Unknown pdu type.\n");      memset(pdu,0,sizeof(pdu));      return;      break;    }  } else {    myprintf(0,"\nUnknown sms status %d\n", status);    memset(pdu,0,sizeof(pdu));    return;  }	  //originator address (OA)  oa.length=hexstr2int(pdu+where,2);  where+=2;  oa.type=hexstr2int(pdu+where,2);  where+=2;  if (oa.length){    if ((oa.type&112)==80){      for(i=where;i<where+oa.length;i+=2){	sprintf(&oa.number[strlen(oa.number)],"%c%c",pdu[i],pdu[i+1]);      }      wide_str=sms_data_7bit_decode(oa.number,(oa.length*4)/7);      t=convert_from_internal(nl_langinfo(CODESET),wide_str,2);      mem_realloc(wide_str,0);      strcpy(oa.number,t);      mem_realloc(t,0);      where+=oa.length;    }else{      if ((oa.type&112)==16) {	sprintf(oa.number,"+");      }      for (i=where;i<where+oa.length;i+=2) {	sprintf(&oa.number[strlen(oa.number)],"%c%c",pdu[i+1],pdu[i]);      }      where+=oa.length;      if (!strcmp(&oa.number[strlen(oa.number)-1],"F")) {	memset(&oa.number[strlen(oa.number)-1],0,1);      }      if (oa.length%2) {	where++;      }    }  }	  //we do not need PID information  pid=hexstr2int(pdu+where,2);  where+=2;	  //DCS information is critical for decoding!!!  dcs=hexstr2int(pdu+where,2);  where+=2;	  switch (pdutype&27) {  case (0<<3)+1: //VP not present    break;  case (1<<3)+1: //VP enhanced    //not yet processed    where+=14;    break;  case (2<<3)+1: //VP relative    sprintf(scts,"%d",hexstr2int(pdu+where,2));    memset(temp,0,sizeof(temp));    where+=2;		    break;  case (3<<3)+1: //VP absolute  case 0: //Service Center Time Stamp (SCTS)    sprintf(temp,"%c%c%c%c%c%c%c%c%c%c%c%c",	    pdu[where+1],pdu[where+0],pdu[where+3],pdu[where+2],	    pdu[where+5],pdu[where+4],pdu[where+7],pdu[where+6],	    pdu[where+9],pdu[where+8],pdu[where+11],pdu[where+10]);    strptime(temp,"%y%m%d%H%M%S",&sctime);    strftime(scts,sizeof(scts)-11,nl_langinfo(D_T_FMT),&sctime);    //timzone handling    //uncomment if you want that    /*sprintf(temp,"%c%c",pdu[where+13],pdu[where+12]);      if (((atoi(temp)%80)/4)<=12) {      if (atoi(temp)>=80) {      sprintf(&scts[strlen(scts)]," (GMT-%02d%02d)",(atoi(temp)%80)/4,(atoi(temp)%320)*15);      } else {      sprintf(&scts[strlen(scts)]," (GMT+%02d%02d)",(atoi(temp)%80)/4,(atoi(temp)%320)*15);      }      }*/    memset(temp,0,sizeof(temp));    where+=14;    break;  }  //user data length, this is hex  udl=hexstr2int(pdu+where,2);  where+=2;	  //user data  if (udl) {    if ((pdutype>>6)&1) {      udh_length=hexstr2int(pdu+where,2);      //udh +udhl drinlassen, dekodieren und dann 1+((udh_length*8)+(udh_length*8)%7)/7 von vorne abschneiden      for (i=2;i<(udh_length*2)+2;i+=2) {	sprintf(&udh[strlen(udh)],"%c%c",pdu[where+i],pdu[where+i+1]);      }    }	        if (    (((dcs>>6)&3)==0 && ((dcs>>2)&3)==0) // 00xx x00x	    || (((dcs>>6)&3)==1 && ((dcs>>2)&3)==0) // 01xx x00x	    || (((dcs>>4)&15)==12) // 1100 xxxx	    || (((dcs>>4)&15)==13) // 1101 xxxx	    || (((dcs>>4)&15)==15 && ((dcs>>2)&1)==0) // 1111 xxxx	    ) {      //all encodings of uncompressed 7bit      wide_str=sms_data_7bit_decode(pdu+where,udl);      if ((pdutype>>6)&1){	t=convert_from_internal(nl_langinfo(CODESET),&wide_str[1+((udh_length*8)+(udh_length*8)%7)/7],2);      } else {	t=convert_from_internal(nl_langinfo(CODESET),wide_str,2);      }      mem_realloc(wide_str,0);      strcpy(ud,t);      mem_realloc(t,0);    } else if (    (((dcs>>6)&3)==0 && ((dcs>>2)&3)==2) //00xx x10x		   || (((dcs>>6)&3)==1 && ((dcs>>2)&3)==2) //01xx x10x		   || (((dcs>>4)&15)==14) // 1110 xxxx		   ) {      //all encodings of uncompressed 16bit unicode      if ((pdutype>>6)&1){	wide_str=convert_from_ucs2(pdu+where+2+(udh_length*2));      } else {	wide_str=convert_from_ucs2(pdu+where);      }      t=convert_from_internal(nl_langinfo(CODESET),wide_str,2);      mem_realloc(wide_str,0);      strcpy(ud,t);      mem_realloc(t,0);      //16bit means real length is only half of octet count      udl /= 2;      /*} else if (    (((dcs>>6)&3)==0 && ((dcs>>2)&3)==1)

⌨️ 快捷键说明

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