| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499 |
- #include "libPDU.h"
- #include "Arduino.h"
- #include "WProgram.h"
- char lookup_ascii8to7[]= {
- NPC7, /* 0 null [NUL] */
- NPC7, /* 1 start of heading [SOH] */
- NPC7, /* 2 start of text [STX] */
- NPC7, /* 3 end of text [ETX] */
- NPC7, /* 4 end of transmission [EOT] */
- NPC7, /* 5 enquiry [ENQ] */
- NPC7, /* 6 acknowledge [ACK] */
- NPC7, /* 7 bell [BEL] */
- NPC7, /* 8 backspace [BS] */
- NPC7, /* 9 horizontal tab [HT] */
- 10, /* 10 line feed [LF] */
- NPC7, /* 11 vertical tab [VT] */
- 10+256, /* 12 form feed [FF] */
- 13, /* 13 carriage return [CR] */
- NPC7, /* 14 shift out [SO] */
- NPC7, /* 15 shift in [SI] */
- NPC7, /* 16 data link escape [DLE] */
- NPC7, /* 17 device control 1 [DC1] */
- NPC7, /* 18 device control 2 [DC2] */
- NPC7, /* 19 device control 3 [DC3] */
- NPC7, /* 20 device control 4 [DC4] */
- NPC7, /* 21 negative acknowledge [NAK] */
- NPC7, /* 22 synchronous idle [SYN] */
- NPC7, /* 23 end of trans. block [ETB] */
- NPC7, /* 24 cancel [CAN] */
- NPC7, /* 25 end of medium [EM] */
- NPC7, /* 26 substitute [SUB] */
- NPC7, /* 27 escape [ESC] */
- NPC7, /* 28 file separator [FS] */
- NPC7, /* 29 group separator [GS] */
- NPC7, /* 30 record separator [RS] */
- NPC7, /* 31 unit separator [US] */
- 32, /* 32 space */
- 33, /* 33 ! exclamation mark */
- 34, /* 34 " double quotation mark */
- 35, /* 35 # number sign */
- 2, /* 36 $ dollar sign */
- 37, /* 37 % percent sign */
- 38, /* 38 & ampersand */
- 39, /* 39 ' apostrophe */
- 40, /* 40 ( left parenthesis */
- 41, /* 41 ) right parenthesis */
- 42, /* 42 * asterisk */
- 43, /* 43 + plus sign */
- 44, /* 44 , comma */
- 45, /* 45 - hyphen */
- 46, /* 46 . period */
- 47, /* 47 / slash, */
- 48, /* 48 0 digit 0 */
- 49, /* 49 1 digit 1 */
- 50, /* 50 2 digit 2 */
- 51, /* 51 3 digit 3 */
- 52, /* 52 4 digit 4 */
- 53, /* 53 5 digit 5 */
- 54, /* 54 6 digit 6 */
- 55, /* 55 7 digit 7 */
- 56, /* 56 8 digit 8 */
- 57, /* 57 9 digit 9 */
- 58, /* 58 : colon */
- 59, /* 59 ; semicolon */
- 60, /* 60 < less-than sign */
- 61, /* 61 = equal sign */
- 62, /* 62 > greater-than sign */
- 63, /* 63 ? question mark */
- 0, /* 64 @ commercial at sign */
- 65, /* 65 A uppercase A */
- 66, /* 66 B uppercase B */
- 67, /* 67 C uppercase C */
- 68, /* 68 D uppercase D */
- 69, /* 69 E uppercase E */
- 70, /* 70 F uppercase F */
- 71, /* 71 G uppercase G */
- 72, /* 72 H uppercase H */
- 73, /* 73 I uppercase I */
- 74, /* 74 J uppercase J */
- 75, /* 75 K uppercase K */
- 76, /* 76 L uppercase L */
- 77, /* 77 M uppercase M */
- 78, /* 78 N uppercase N */
- 79, /* 79 O uppercase O */
- 80, /* 80 P uppercase P */
- 81, /* 81 Q uppercase Q */
- 82, /* 82 R uppercase R */
- 83, /* 83 S uppercase S */
- 84, /* 84 T uppercase T */
- 85, /* 85 U uppercase U */
- 86, /* 86 V uppercase V */
- 87, /* 87 W uppercase W */
- 88, /* 88 X uppercase X */
- 89, /* 89 Y uppercase Y */
- 90, /* 90 Z uppercase Z */
- 60+256, /* 91 [ left square bracket */
- 47+256, /* 92 \ backslash */
- 62+256, /* 93 ] right square bracket */
- 20+256, /* 94 ^ circumflex accent */
- 17, /* 95 _ underscore */
- -39, /* 96 ` back apostrophe */
- 97, /* 97 a lowercase a */
- 98, /* 98 b lowercase b */
- 99, /* 99 c lowercase c */
- 100, /* 100 d lowercase d */
- 101, /* 101 e lowercase e */
- 102, /* 102 f lowercase f */
- 103, /* 103 g lowercase g */
- 104, /* 104 h lowercase h */
- 105, /* 105 i lowercase i */
- 106, /* 106 j lowercase j */
- 107, /* 107 k lowercase k */
- 108, /* 108 l lowercase l */
- 109, /* 109 m lowercase m */
- 110, /* 110 n lowercase n */
- 111, /* 111 o lowercase o */
- 112, /* 112 p lowercase p */
- 113, /* 113 q lowercase q */
- 114, /* 114 r lowercase r */
- 115, /* 115 s lowercase s */
- 116, /* 116 t lowercase t */
- 117, /* 117 u lowercase u */
- 118, /* 118 v lowercase v */
- 119, /* 119 w lowercase w */
- 120, /* 120 x lowercase x */
- 121, /* 121 y lowercase y */
- 122, /* 122 z lowercase z */
- 40+256, /* 123 { left brace */
- 64+256, /* 124 | vertical bar */
- 41+256, /* 125 } right brace */
- 61+256, /* 126 ~ tilde accent */
- NPC7, /* 127 delete [DEL] */
- NPC7, /* 128 */
- NPC7, /* 129 */
- -39, /* 130 low left rising single quote */
- -102, /* 131 lowercase italic f */
- -34, /* 132 low left rising double quote */
- NPC7, /* 133 low horizontal ellipsis */
- NPC7, /* 134 dagger mark */
- NPC7, /* 135 double dagger mark */
- NPC7, /* 136 letter modifying circumflex */
- NPC7, /* 137 per thousand (mille) sign */
- -83, /* 138 uppercase S caron or hacek */
- -39, /* 139 left single angle quote mark */
- -214, /* 140 uppercase OE ligature */
- NPC7, /* 141 */
- NPC7, /* 142 */
- NPC7, /* 143 */
- NPC7, /* 144 */
- -39, /* 145 left single quotation mark */
- -39, /* 146 right single quote mark */
- -34, /* 147 left double quotation mark */
- -34, /* 148 right double quote mark */
- -42, /* 149 round filled bullet */
- -45, /* 150 en dash */
- -45, /* 151 em dash */
- -39, /* 152 small spacing tilde accent */
- NPC7, /* 153 trademark sign */
- -115, /* 154 lowercase s caron or hacek */
- -39, /* 155 right single angle quote mark */
- -111, /* 156 lowercase oe ligature */
- NPC7, /* 157 */
- NPC7, /* 158 */
- -89, /* 159 uppercase Y dieresis or umlaut */
- -32, /* 160 ? non-breaking space */
- 64, /* 161 ? inverted exclamation mark */
- -99, /* 162 ? cent sign */
- 1, /* 163 ? pound sterling sign */
- 36, /* 164 ? general currency sign */
- 3, /* 165 ? yen sign */
- -33, /* 166 ? broken vertical bar */
- 95, /* 167 ? section sign */
- -34, /* 168 ? spacing dieresis or umlaut */
- NPC7, /* 169 ? copyright sign */
- NPC7, /* 170 ? feminine ordinal indicator */
- -60, /* 171 ? left (double) angle quote */
- NPC7, /* 172 ? logical not sign */
- -45, /* 173 ? soft hyphen */
- NPC7, /* 174 ? registered trademark sign */
- NPC7, /* 175 ? spacing macron (long) accent */
- NPC7, /* 176 ? degree sign */
- NPC7, /* 177 ? plus-or-minus sign */
- -50, /* 178 ? superscript 2 */
- -51, /* 179 ? superscript 3 */
- -39, /* 180 ? spacing acute accent */
- -117, /* 181 ? micro sign */
- NPC7, /* 182 ? paragraph sign, pilcrow sign */
- NPC7, /* 183 ? middle dot, centered dot */
- NPC7, /* 184 ? spacing cedilla */
- -49, /* 185 ? superscript 1 */
- NPC7, /* 186 ? masculine ordinal indicator */
- -62, /* 187 ? right (double) angle quote (guillemet) */
- NPC7, /* 188 ? fraction 1/4 */
- NPC7, /* 189 ? fraction 1/2 */
- NPC7, /* 190 ? fraction 3/4 */
- 96, /* 191 ? inverted question mark */
- -65, /* 192 ? uppercase A grave */
- -65, /* 193 ? uppercase A acute */
- -65, /* 194 ? uppercase A circumflex */
- -65, /* 195 ? uppercase A tilde */
- 91, /* 196 ? uppercase A dieresis or umlaut */
- 14, /* 197 ? uppercase A ring */
- 28, /* 198 ? uppercase AE ligature */
- 9, /* 199 ? uppercase C cedilla */
- -31, /* 200 ? uppercase E grave */
- 31, /* 201 ? uppercase E acute */
- -31, /* 202 ? uppercase E circumflex */
- -31, /* 203 ? uppercase E dieresis or umlaut */
- -73, /* 204 ? uppercase I grave */
- -73, /* 205 ? uppercase I acute */
- -73, /* 206 ? uppercase I circumflex */
- -73, /* 207 ? uppercase I dieresis or umlaut */
- -68, /* 208 ? uppercase ETH */
- 93, /* 209 ? uppercase N tilde */
- -79, /* 210 ? uppercase O grave */
- -79, /* 211 ? uppercase O acute */
- -79, /* 212 ? uppercase O circumflex */
- -79, /* 213 ? uppercase O tilde */
- 92, /* 214 ? uppercase O dieresis or umlaut */
- -42, /* 215 ? multiplication sign */
- 11, /* 216 ? uppercase O slash */
- -85, /* 217 ? uppercase U grave */
- -85, /* 218 ? uppercase U acute */
- -85, /* 219 ? uppercase U circumflex */
- 94, /* 220 ? uppercase U dieresis or umlaut */
- -89, /* 221 ? uppercase Y acute */
- NPC7, /* 222 ? uppercase THORN */
- 30, /* 223 ? lowercase sharp s, sz ligature */
- 127, /* 224 ? lowercase a grave */
- -97, /* 225 ? lowercase a acute */
- -97, /* 226 ? lowercase a circumflex */
- -97, /* 227 ? lowercase a tilde */
- 123, /* 228 ? lowercase a dieresis or umlaut */
- 15, /* 229 ? lowercase a ring */
- 29, /* 230 ? lowercase ae ligature */
- -9, /* 231 ? lowercase c cedilla */
- 4, /* 232 ? lowercase e grave */
- 5, /* 233 ? lowercase e acute */
- -101, /* 234 ? lowercase e circumflex */
- -101, /* 235 ? lowercase e dieresis or umlaut */
- 7, /* 236 ? lowercase i grave */
- 7, /* 237 ? lowercase i acute */
- -105, /* 238 ? lowercase i circumflex */
- -105, /* 239 ? lowercase i dieresis or umlaut */
- NPC7, /* 240 ? lowercase eth */
- 125, /* 241 ? lowercase n tilde */
- 8, /* 242 ? lowercase o grave */
- -111, /* 243 ? lowercase o acute */
- -111, /* 244 ? lowercase o circumflex */
- -111, /* 245 ? lowercase o tilde */
- 124, /* 246 ? lowercase o dieresis or umlaut */
- -47, /* 247 ? division sign */
- 12, /* 248 ? lowercase o slash */
- 6, /* 249 ? lowercase u grave */
- -117, /* 250 ? lowercase u acute */
- -117, /* 251 ? lowercase u circumflex */
- 126, /* 252 ? lowercase u dieresis or umlaut */
- -121, /* 253 ? lowercase y acute */
- NPC7, /* 254 ? lowercase thorn */
- -121 /* 255 ? lowercase y dieresis or umlaut */
- };
- String PDU::decode(String pdu_text) {
- uint8_t len = strtol(pdu_text.substring(0, 2).c_str(), NULL, 16); //the fist byte contains the number of chars
- return pdu_decode(pdu_text.substring(2), len);
- }
- String PDU::decode(String pdu_text, uint8_t len) {
- char plain_bytes[256];
- byte high_mask = 128; // byte:10000000;
- byte low_mask;
- byte shift = 0;
- byte this_byte;
- byte high_byte_new = 0;
- byte high_byte_old = 0;
- byte low_byte = 0;
- int y = 0;
- int i = 0;
- for (y = 0; y < len ; y++) {
- this_byte = strtol(pdu_text.substring(i * 2, (i * 2) + 2).c_str(), NULL, 16);
- low_mask = high_mask ^ 0xFF; //invert
- high_byte_new = this_byte & high_mask; // 10000000 = 11000111 & 10000000
- low_byte = this_byte & low_mask; // 01000111 = 11000111 & 01111111
- plain_bytes[y] = low_byte << shift; // 10001110
- high_byte_old = high_byte_old >> (8 - shift); // 00000001
- plain_bytes[y] = plain_bytes[y] + high_byte_old; // 10001111
- if (shift == 6) {
- y++;
- plain_bytes[y] = high_byte_new >> 1;
- }
- high_mask = high_mask >> 1; // 10000000 > 01000000
- high_mask = high_mask + 128; // 01000000 > 11000000
- if (high_mask == 255)high_mask = 128; // 11111111 > 10000000
- low_mask = high_mask ^ 0xFF; // invert
- high_byte_old = high_byte_new;
- shift++;
- if (shift == 7) {
- shift = 0;
- }
- i++;
- }
- plain_bytes[y] = 0;
- char *plain_text = new char[y];
- strcpy(plain_text, plain_bytes);
- return plain_text;
- }
- String PDU::semiOctetToString (String semiOctet) {
- unsigned int i;
- String OctetString;
- for (i = 0; i < ( semiOctet.length() / 2 ); i++) {
- OctetString += semiOctet.substring(i*2 + 1,i*2 + 1+1);
- OctetString += semiOctet.substring(i*2, i*2+1);
- }
- return OctetString;
- }
- String PDU::stringToSemiOctet (String StringData) {
- if ( StringData.length() % 2 != 0 ) {
- StringData += "F";
- }
- return semiOctetToString(StringData);
- }
- int PDU::hexStringToInt (String hexString) {
- unsigned int i;
- int charvalue;
- int returnvalue = 0;
- for (i = 0; i < hexString.length(); i++) {
- if ( hexString[i] >= 'a' && hexString[i] <= 'f' ) {
- charvalue = (int) hexString[i] - 87;
- }
- if ( hexString[i] >= 'A' && hexString[i] <= 'F' ) {
- charvalue = (int) hexString[i] - 55;
- }
- if ( hexString[i] >= '0' && hexString[i] <= '9' ) {
- charvalue = (int) hexString[i] - 48;
- }
- returnvalue += charvalue * ( pow(16, (int)(hexString.length() - (i + 1)) ));
- }
- return returnvalue;
- }
- String PDU::intToHexString (int integer) {
- String hexString = "";
- //Conversion from intToHex
- char buf[3];
- sprintf(buf,"%X",integer);
- hexString = (String)buf;
- //Prepend a 0 when not even
- if ( hexString.length() % 2 != 0 ){
- hexString = "0" + hexString;
- }
- return hexString;
- }
- int PDU::binStringToInt (String binString) {
- unsigned int pos;
- int integerReturn = 0;
- int base = 2;
- for (pos = 0; pos < binString.length(); pos++) {
- if ( binString.substring(pos, pos+1) == "1" ) {
- integerReturn += pow(base, (binString.length() - (pos + 1)) );
- }
- }
- return integerReturn;
- }
- String PDU::intToBinString (int integer) {
- String stringReturn;
- if (integer <= 0) {
- return "0";
- }
- while ( integer > 0 ) {
- if ( integer % 2 == 1 ) {
- stringReturn = "1" + stringReturn;
- --integer;
- } else {
- stringReturn = "0" + stringReturn;
- }
- integer = integer / 2;
- }
- //Changed 8 to 7 because the characters are in septets
- while ( stringReturn.length() % 7 != 0 ) {
- stringReturn = "0" + stringReturn;
- }
- return stringReturn;
- }
- int PDU::pow(int n, int i)
- {
- if (i == 0)
- return 1;
- else if (i == 1)
- return n;
- else {
- int partial = pow(n, i / 2);
- if (i % 2 == 0)
- return partial * partial;
- else
- return partial * partial * n;
- }
- }
- int PDU::setText( String smstext ) {
- if ( smstext.length() > 160 ) {
- return 0;
- }
- this->tp_text = smstext;
- return 1;
- }
- int PDU::setSender( String number ) {
- this->sender_type_of_address = 146;
- if ( number.substring(0,1) == "+" ) {
- this->sender_type_of_address = 145;
- this->sender_number = number.substring(1, number.length());
- } else {
- this->sender_number = number;
- }
- this->sender_length = this->sender_number.length();
- if ( this->sender_number.length() % 2 == 1 ) {
- this->sender_number + "F";
- }
- return 1;
- }
- String PDU::userTextTo7(void) {
- unsigned int pos;
- String current, octetFirst, octetSecond, currentOctet;
- String output;
- for (pos = 0; pos < this->tp_text.length(); pos++) {
- current = intToBinString(lookup_ascii8to7[ this->tp_text[pos] ]);
- if ( ( pos != 0 ) && ( pos % 8 != 0 ) ) {
- octetFirst = current.substring(7 - ( pos % 8 ), current.length() );
- currentOctet = octetFirst + octetSecond;
- output += intToHexString(binStringToInt(currentOctet));
- octetSecond = current.substring(0, 7 - (pos % 8));
- }
- else {
- octetSecond = current.substring(0, 7 - (pos % 8));
- }
- if ( ( pos + 1 == this->tp_text.length() ) && ( octetSecond != "" ) ) {
- output += intToHexString(binStringToInt(octetSecond));
- }
- }
- return output;
- }
- String PDU::encode() {
- String pduString;
- pduString = "00"; // SMSC_LENGHT
- pduString += "1100"; // FIRST OCTET ( message submit & tp reference)
- pduString += intToHexString(this->sender_length); // SENDER_LENGHT
- pduString += intToHexString(this->sender_type_of_address); // SENDER_TYPE
- pduString += stringToSemiOctet(this->sender_number); // SENDER_NUMBER
- pduString += "0000"; // TP-PID TP-DCS ( 7-bit default encoding )
- pduString += "AA"; // VALIDITY ( 4 days )
- pduString += intToHexString(this->tp_text.length());
- pduString += userTextTo7();
- return pduString;
- }
|