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

📄 pdu.c

📁 GSM猫管理程序
💻 C
📖 第 1 页 / 共 4 页
字号:
/*SMS Server Tools 3Copyright (C) Keijo Kasvihttp://smstools3.kekekasvi.com/Based on SMS Server Tools 2 from Stefan Fringshttp://www.meinemullemaus.de/This program is free software unless you got it under another license directlyfrom the author. You can redistribute it and/or modify it under the terms ofthe 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 <string.h>#include <stdio.h>#include <stdarg.h>#include <stdlib.h>#include <ctype.h>#include <syslog.h>#include "pdu.h"#include "smsd_cfg.h"#include "logging.h"#include "charset.h" // required for conversions of partial text content.#define MAX_ADDRESS_LENGTH 50#define MAX_SMSC_ADDRESS_LENGTH 30char *err_too_short = "string is too short";char *err_pdu_content = "invalid character(s) in string";int add_warning(char *buffer, char *format, ...){  int result = 1;  va_list argp;  char text[2048];  char *title = "Warning: ";  va_start(argp, format);  vsnprintf(text, sizeof(text), format, argp);  va_end(argp);  if (buffer)  {    if (strlen(buffer) + strlen(text) +strlen(title) +1/* for \n */ < SIZE_WARNING_HEADERS)      sprintf(strchr(buffer, 0), "%s%s\n", title, text);    else    {      result = 0;      writelogfile(LOG_ERR, process_title, "PDU %s%s", title, text);    }  }  return result;}void pdu_error(char **err_str, char *title, int position, int length, char *format, ...){  va_list argp;  char text[2048];  char *default_title = "PDU ERROR: ";  char *used_title;  char tmp[51];  va_start(argp, format);  vsnprintf(text, sizeof(text), format, argp);  va_end(argp);  used_title = (title)? title : default_title;  if (position >= 0)  {    if (length > 0)      sprintf(tmp, "Position %i,%i: ", position +1, length);    else      sprintf(tmp, "Position %i: ", position +1);  }  else    *tmp = 0;  if (!(*err_str))  {    if ((*err_str = (char *)malloc(strlen(tmp) +strlen(text) +strlen(used_title) +2)))      *err_str[0] = 0;  }  else    *err_str = (char *)realloc((void *)*err_str, strlen(*err_str) +strlen(used_title) +strlen(tmp) +strlen(text) +2);  if (*err_str)    sprintf(strchr(*err_str, 0), "%s%s%s\n", used_title, tmp, text);}int isXdigit(char ch){  if ((ch >= '0' && ch <= '9') || (ch >= 'A' && ch <= 'F'))    return 1;  return 0;}/* Swap every second character */void swapchars(char* string) {  int Length;  int position;  char c;  Length=strlen(string);  for (position=0; position<Length-1; position+=2)  {    c=string[position];    string[position]=string[position+1];    string[position+1]=c;  }}// Converts an ascii text to a pdu string // text might contain zero values because this is a valid character code in sms// character set. Therefore we need the length parameter.// If udh is not 0, then insert it to the beginning of the message.// The string must be in hex-dump format: "05 00 03 AF 02 01". // The first byte is the size of the UDH.int text2pdu(char* text, int length, char* pdu, char* udh){  char tmp[500];  char octett[10];  int pdubitposition;  int pdubyteposition=0;  int character;  int bit;  int pdubitnr;  int counted_characters=0;  int udh_size_octets;   // size of the udh in octets, should equal to the first byte + 1  int udh_size_septets;  // size of udh in septets (7bit text characters)  int fillbits;          // number of filler bits between udh and ud.  int counter;#ifdef DEBUGMSG  printf("!! text2pdu(text=..., length=%i, pdu=..., udh=%s\n",length,udh);#endif  pdu[0]=0;  // Check the udh  if (udh)  {    udh_size_octets=(strlen(udh)+2)/3;    udh_size_septets=((udh_size_octets)*8+6)/7;    fillbits=7-(udh_size_octets % 7);    if (fillbits==7)      fillbits=0;    // copy udh to pdu, skipping the space characters    for (counter=0; counter<udh_size_octets; counter++)    {      pdu[counter*2]=udh[counter*3];      pdu[counter*2+1]=udh[counter*3+1];    }    pdu[counter*2]=0;#ifdef DEBUGMSG  printf("!! pdu=%s, fillbits=%i\n",pdu,fillbits);#endif  }   else  {    udh_size_octets=0;    udh_size_septets=0;     fillbits=0;  }  // limit size of the message to maximum allowed size  if (length>maxsms_pdu-udh_size_septets)    length=maxsms_pdu-udh_size_septets;  //clear the tmp buffer  for (character=0;character<sizeof(tmp);character++)    tmp[character]=0;  // Convert 8bit text stream to 7bit stream  for (character=0;character<length;character++)  {    counted_characters++;    for (bit=0;bit<7;bit++)    {      pdubitnr=7*character+bit+fillbits;      pdubyteposition=pdubitnr/8;      pdubitposition=pdubitnr%8;      if (text[character] & (1<<bit))        tmp[pdubyteposition]=tmp[pdubyteposition] | (1<<pdubitposition);      else        tmp[pdubyteposition]=tmp[pdubyteposition] & ~(1<<pdubitposition);    }  }  tmp[pdubyteposition+1]=0;  // convert 7bit stream to hex-dump  for (character=0;character<=pdubyteposition; character++)  {    sprintf(octett,"%02X",(unsigned char) tmp[character]);    strcat(pdu,octett);  }#ifdef DEBUGMSG  printf("!! pdu=%s\n",pdu);#endif  return counted_characters+udh_size_septets;}/* Converts binary to PDU string, this is basically a hex dump. */void binary2pdu(char* binary, int length, char* pdu){  int character;  char octett[10];  if (length>maxsms_binary)    length=maxsms_binary;  pdu[0]=0;  for (character=0;character<length; character++)  {    sprintf(octett,"%02X",(unsigned char) binary[character]);    strcat(pdu,octett);  }}// Make the PDU string from a mesage text and destination phone number.// The destination variable pdu has to be big enough. // alphabet indicates the character set of the message.// flash_sms enables the flash flag.// mode select the pdu version (old or new).// if udh is true, then udh_data contains the optional user data header in hex dump, example: "05 00 03 AF 02 01"void make_pdu(char* number, char* message, int messagelen, int alphabet, int flash_sms, int report, int with_udh,              char* udh_data, char* mode, char* pdu, int validity, int replace_msg){  int coding;  int flags;  char tmp[50];  char tmp2[500];  int numberformat;  int numberlength;  char *p;  int l;  if (number[0]=='s')  // Is number starts with s, then send it without number format indicator  {    numberformat=129;    strcpy(tmp,number+1);  }  else  {    numberformat=145;    strcpy(tmp,number);  }  numberlength=strlen(tmp);  // terminate the number with F if the length is odd  if (numberlength%2)    strcat(tmp,"F");  // Swap every second character  swapchars(tmp);  flags=1; // SMS-Sumbit MS to SMSC  if (with_udh)    flags+=64; // User Data Header  if (strcmp(mode,"old")!=0)    flags+=16; // Validity field  if (report>0)    flags+=32; // Request Status Report  if (alphabet == 1)    coding = 4; // 8bit binary  else if (alphabet == 2)    coding = 8; // 16bit  else    coding = 0; // 7bit  if (flash_sms > 0)    coding += 0x10; // Bits 1 and 0 have a message class meaning (class 0, alert)  /* Create the PDU string of the message */  if (alphabet==1 || alphabet==2)  {    // Unicode message can be concatenated:    //if (alphabet == 2 && with_udh)    // Binary message can be concatenated too:    if (with_udh)    {      strcpy(tmp2, udh_data);      while ((p = strchr(tmp2, ' ')))        strcpy(p, p +1);      l = strlen(tmp2) /2;      binary2pdu(message, messagelen, strchr(tmp2, 0));      messagelen += l;    }    else      binary2pdu(message,messagelen,tmp2);  }  else    messagelen=text2pdu(message,messagelen,tmp2,udh_data);  /* concatenate the first part of the PDU string */  if (strcmp(mode,"old")==0)    sprintf(pdu,"%02X00%02X%02X%s00%02X%02X",flags,numberlength,numberformat,tmp,coding,messagelen);  else  {    if (validity < 0 || validity > 255)      validity = validity_period;    sprintf(pdu, "00%02X00%02X%02X%s%02X%02X%02X%02X",            flags, numberlength, numberformat, tmp,            (replace_msg >= 1 && replace_msg <= 7)? 0x40 +replace_msg : 0,            coding, validity, messagelen);  }  /* concatenate the text to the PDU string */  strcat(pdu,tmp2);}int octet2bin(char* octet) /* converts an octet to a 8-Bit value */{  int result=0;  if (octet[0]>57)    result+=octet[0]-55;  else    result+=octet[0]-48;  result=result<<4;  if (octet[1]>57)    result+=octet[1]-55;  else    result+=octet[1]-48;  return result;}// Converts an octet to a 8bit value,// returns < in case of error.int octet2bin_check(char *octet){  if (octet[0] == 0)    return -1;  if (octet[1] == 0)    return -2;  if (!isXdigit(octet[0]))    return -3;  if (!isXdigit(octet[1]))    return -4;  return octet2bin(octet);}// Return value: -1 = error, 0 = not found.// 1 = found 8bit, 2 = found 16bit.// udh must be in header format, "05 00 03 02 03 02 "int get_remove_concatenation(char *udh, int *message_id, int *parts, int *part){  int udh_length;  int octets;  int idx;  char *con_start = NULL;  int id;  int i;  char tmp[10];  if ((udh_length = octet2bin_check(udh)) < 0)    return -1;  octets = strlen(udh) /3;  idx = 1;  while (idx < octets)  {    if ((id = octet2bin_check(udh +idx *2 +idx)) < 0)      return -1;    if (id == 0x00 || id == 0x08)    {      // It's here.      con_start = udh +idx *2 +idx;      if (++idx >= octets)        return -1;      i = octet2bin_check(udh +idx *2 +idx);      if ((id == 0x00 && i != 0x03) ||          (id == 0x08 && i != 0x04))        return -1;      if (++idx >= octets)        return -1;      if ((*message_id = octet2bin_check(udh +idx *2 +idx)) < 0)        return -1;      if (id == 0x08)      {        if (++idx >= octets)          return -1;        if ((i = octet2bin_check(udh +idx *2 +idx)) < 0)          return -1;        *message_id = *message_id *0xFF +i;      }      if (++idx >= octets)        return -1;      if ((*parts = octet2bin_check(udh +idx *2 +idx)) < 0)        return -1;      if (++idx >= octets)        return -1;      if ((*part = octet2bin_check(udh +idx *2 +idx)) < 0)        return -1;      if (++idx >= octets)        *con_start = 0;      else        strcpy(con_start, udh +idx *2 +idx);      i = (id == 0x00)? 5 : 6;      udh_length -= i;      if (udh_length > 0)      {

⌨️ 快捷键说明

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