/* * * This file is part of Smsq. * * Smsq 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. * * Smsq is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with Smsq; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * * Peter Harper * * $Id: gsm0338.c,v 1.1 2003/12/02 06:17:38 rmello Exp $ */ static char rcsid[] = "@(#) $Id: gsm0338.c,v 1.1 2003/12/02 06:17:38 rmello Exp $"; #include "ns.h" /* * * 8bit to 7bit conversion table. * * 00 01 02 03 04 05 06 07 * 08 09 0a 0b 0c 0d 0e 0f * 00 - 0f */ int g_gsm0338_smsq_8to7[256] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0a, 0x00, 0x1b0a,0x0d, 0x00, 0x00, // 10 - 1f 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 20 - 2f 0x20, 0x21, 0x22, 0x23, 0x02, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, // 30 - 3f 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0x3e, 0x3f, // 40 - 4f 0x00, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4a, 0x4b, 0x4c, 0x4d, 0x4e, 0x4f, // 50 - 5f 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5a, 0x1b3c,0x1b2f,0x1b3e,0x1b14,0x11, // 60 - 6f 0x00, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x6b, 0x6c, 0x6d, 0x6e, 0x6f, // 70 - 7f 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a, 0x1b28,0x1b40,0x1b29,0x1b3d,0x00, // 00, 01, 02, 03, 04, 05, 06, 07, // 08, 09, 0a, 0b, 0c, 0d, 0e, 0f, // 80 - 8f 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 90 - 9f 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // a0 - af // Note, difference here between 0xa4 as 1b65 (euro sign) - ISO-8859-15 // and 0xa4 as 24 (currency sign) - ISO-8859-1 0x00, 0x40, 0x00, 0x01, 0x1b65,0x03, 0x00, 0x5f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // b0 - bf 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, // c0 - cf 0x00, 0x00, 0x00, 0x00, 0x5b, 0x0e, 0x1c, 0x09, 0x00, 0x00, 0x1f, 0x00, 0x00, 0x00, 0x00, 0x00, // d0 - df 0x00, 0x5d, 0x00, 0x00, 0x00, 0x00, 0x5c, 0x00, 0x0b, 0x00, 0x00, 0x00, 0x5e, 0x00, 0x00, 0x1e, // e0 - ef 0x7f, 0x00, 0x00, 0x00, 0x7b, 0x0f, 0x1d, 0x00, 0x04, 0x05, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, // f0 - ff 0x00, 0x7d, 0x08, 0x00, 0x00, 0x00, 0x7c, 0x00, 0x0c, 0x00, 0x06, 0x00, 0x7e, 0x00, 0x00, 0x00}; int g_gsm0338_smsq_7to8[128]; /* * Gsm 7bit to 8bit. * Fudge the anomoly between ISO-8859-15 and ISO-8859-1 (see above). */ int gsm0338_init(void) { int i; for (i = 0; i < 128; i++) { g_gsm0338_smsq_7to8[i] = 32; } for (i = 0; i < 256; i++) { if (g_gsm0338_smsq_8to7[i] <= 0x7f) { g_gsm0338_smsq_7to8[g_gsm0338_smsq_8to7[i]] = i; } } /* * Fudge the anomoly between ISO-8859-15 and ISO-8859-1 (see above). */ g_gsm0338_smsq_7to8[0x24] = 0xa4; return NS_FALSE; } void gsm0338_pack_7bit(unsigned char *bits7_ptr, int *bits7_len_ptr, char *bits8_ptr) { int i; int total_chars; int bits8_len; unsigned char working_byte; int cur_char; int extra_char; int bottom_bits, top_bits; int bottom_mask, top_mask; bits8_len = strlen(bits8_ptr); *bits7_len_ptr = 0; working_byte = 0; total_chars = 0; for (i = 0; i < bits8_len; i++) { cur_char = g_gsm0338_smsq_8to7[(int)bits8_ptr[i]]; extra_char = -1; if (cur_char > 0xff) { cur_char = (cur_char & 0xff00) >> 8; extra_char = (cur_char & 0xff); } bottom_bits = total_chars % 8; top_bits = 8 - bottom_bits; bottom_mask = (1 << bottom_bits) - 1; top_mask = 0xff - bottom_mask; working_byte = ((bottom_mask & cur_char) << top_bits) | working_byte; if (bottom_bits > 0) { bits7_ptr[*bits7_len_ptr] = working_byte; (*bits7_len_ptr)++; working_byte = 0; } working_byte = ((top_mask & cur_char) >> bottom_bits) | working_byte; total_chars++; if (extra_char != -1) { cur_char = extra_char; bottom_bits = total_chars % 8; top_bits = 8 - bottom_bits; bottom_mask = (1 << bottom_bits) - 1; top_mask = 0xff - bottom_mask; working_byte = ((bottom_mask & cur_char) << top_bits) | working_byte; if (bottom_bits > 0) { bits7_ptr[*bits7_len_ptr] = working_byte; (*bits7_len_ptr)++; working_byte = 0; } working_byte = ((top_mask & cur_char) >> bottom_bits) | working_byte; total_chars++; } } /* * If there's anything in the final octet, add it. */ if (top_bits > 0) { bits7_ptr[*bits7_len_ptr] = working_byte; (*bits7_len_ptr)++; } *(bits7_len_ptr) = (bits8_len * 7) / 8; if ( ((bits8_len * 7) % 8) != 0 ) { (*bits7_len_ptr)++; } } void gsm0338_unpack_7bit(char *bits8_ptr, unsigned char *bits7_ptr, int bits7_len, int unpacked_data_len) { int i; int bits8_len; int carry; int bottom_bits; int bottom_mask; int top_mask; int cur_char; char tmp[9]; bits8_len = 0; carry = 0; bottom_bits = 7; for (i = 0; i < bits7_len; i++) { bottom_mask = (1 << bottom_bits) - 1; top_mask = 0xff - bottom_mask; cur_char = carry + ((bits7_ptr[i] & bottom_mask) << (7 - bottom_bits)); carry = (bits7_ptr[i] & top_mask) >> bottom_bits; bits8_ptr[bits8_len] = g_gsm0338_smsq_7to8[cur_char]; bits8_len++; bottom_bits--; // if (bottom_bits == 0 && // i != (bits7_len - 1)) { if (bottom_bits == 0) { bottom_bits = 7; cur_char = carry; bits8_ptr[bits8_len] = g_gsm0338_smsq_7to8[cur_char]; bits8_len++; carry = 0; } } bits8_len = unpacked_data_len; bits8_ptr[bits8_len] = '\0'; }