/* Copyright (C) 2007-2008 The Android Open Source Project
**
** This software is licensed under the terms of the GNU General Public
** License version 2, as published by the Free Software Foundation, and
** may be copied, distributed, and modified under those terms.
**
** This program 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.
*/
#include "sms.h"
#include "gsm.h"
#include <memory.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>

#define  DEBUG  1

#if 1
#  include "android/utils/debug.h"
#  define  D_ACTIVE  VERBOSE_CHECK(modem)
#else
#  define  D_ACTIVE  DEBUG
#endif

#if DEBUG
#  define  D(...)  VERBOSE_PRINT(modem,__VA_ARGS__)
#else
#  define  D(...)  ((void)0)
#endif

/* maximum number of data bytes in a SMS data message */
#define  MAX_USER_DATA_BYTES   140

/* maximum number of 7-bit septets in a SMS text message */
#define  MAX_USER_DATA_SEPTETS  160

/* size of the user data header in bytes */
#define  USER_DATA_HEADER_SIZE   6

/** MESSAGE TEXT
 **/
int
sms_utf8_from_message_str( const char*  str, int  strlen, unsigned char*  utf8, int  utf8len )
{
    cbytes_t  p       = (cbytes_t)str;
    cbytes_t  end     = p + strlen;
    int       count   = 0;
    int       escaped = 0;

    while (p < end)
    {
        int  c = p[0];

        /* read the value from the string */
        p += 1;
        if (c >= 128) {
            if ((c & 0xe0) == 0xc0)
                c &= 0x1f;
            else if ((c & 0xf0) == 0xe0)
                c &= 0x0f;
            else
                c &= 0x07;

            while (p < end && (p[0] & 0xc0) == 0x80) {
                c = (c << 6) | (p[0] & 0x3f);
                p++;
            }
        }
        if (escaped) {
            switch (c) {
                case '\\':
                    break;
                case 'n':  /* \n is line feed */
                    c = 10;
                    break;

                case 'x':  /* \xNN, where NN is a 2-digit hexadecimal value */
                    if (p+2 > end)
                        return -1;
                    c = gsm_hex2_to_byte( (const char*)p );
                    if (c < 0)
                        return -1;
                    p += 2;
                    break;

                case 'u':  /* \uNNNN where NNNN is a 4-digiti hexadecimal value */
                    if (p + 4 > end)
                        return -1;
                    c = gsm_hex4_to_short( (const char*)p );
                    if (c < 0)
                        return -1;
                    p += 4;
                    break;

                default:  /* invalid escape, return -1 */
                    return -1;
            }
            escaped = 0;
        }
        else if (c == '\\')
        {
            escaped = 1;
            continue;
        }

        /* now, try to write it to the destination */
        if (c < 128) {
            if (count < utf8len)
                utf8[count] = (byte_t) c;
            count += 1;
        }
        else if (c < 0x800) {
            if (count < utf8len)
                utf8[count]   = (byte_t)(0xc0 | ((c >> 6) & 0x1f));
            if (count+1 < utf8len)
                utf8[count+1] = (byte_t)(0x80 | (c & 0x3f));
            count += 2;
        }
        else {
            if (count < utf8len)
                utf8[count]   = (byte_t)(0xc0 | ((c >> 12) & 0xf));
            if (count+1 < utf8len)
                utf8[count+1] = (byte_t)(0x80 | ((c >> 6) & 0x3f));
            if (count+2 < utf8len)
                utf8[count+2] = (byte_t)(0x80 | (c & 0x3f));
            count += 3;
        }
    }

    if (escaped)   /* bad final escape */
        return -1;

    return count;
}

/* to convert utf-8 to a message string, we only need to deal with control characters
 * and that's it */
int  sms_utf8_to_message_str( const unsigned char*  utf8, int  utf8len, char*  str, int  strlen )
{
    cbytes_t  p = utf8;
    cbytes_t  end = p + utf8len;
    int       count   = 0;

    while (p < end)
    {
        int  c      = p[0];
        int  escape = 0;

        /* read the value from the string */
        p += 1;
        if (c >= 128) {
            if ((c & 0xe0) == 0xc0)
                c &= 0x1f;
            else if ((c & 0xf0) == 0xe0)
                c &= 0x0f;
            else
                c &= 0x07;
            p++;
            while (p < end && (p[0] & 0xc0) == 0x80) {
                c = (c << 6) | (p[0] & 0x3f);
                p++;
            }
        }

        if (c < ' ') {
            escape = 1;
            if (c == '\n') {
                c      = 'n';
                escape = 2;
            }
        }
        else if (c == '\\')
            escape = 2;

        switch (escape) {
            case 0:
                if (c < 128) {
                    if (count < strlen)
                        str[count] = (char) c;
                    count += 1;
                }
                else if (c < 0x800) {
                    if (count < strlen)
                        str[count]   = (byte_t)(0xc0 | ((c >> 6) & 0x1f));
                    if (count+1 < strlen)
                        str[count+1] = (byte_t)(0x80 | (c & 0x3f));
                    count += 2;
                }
                else {
                    if (count < strlen)
                        str[count]   = (byte_t)(0xc0 | ((c >> 12) & 0xf));
                    if (count+1 < strlen)
                        str[count+1] = (byte_t)(0x80 | ((c >> 6) & 0x3f));
                    if (count+2 < strlen)
                        str[count+2] = (byte_t)(0x80 | (c & 0x3f));
                    count += 3;
                }
                break;

            case 1:
                if (count+3 < strlen) {
                    str[count+0] = '\\';
                    str[count+1] = 'x';
                    gsm_hex_from_byte(str + count + 2, c);
                }
                count += 4;
                break;

            default:
                if (count+2 < strlen) {
                    str[count+0] = '\\';
                    str[count+1] = (char) c;
                }
                count += 2;
        }
    }
    return count;
}


/** TIMESTAMPS
 **/
void
sms_timestamp_now( SmsTimeStamp  stamp )
{
    time_t     now_time = time(NULL);
    struct tm  gm       = *(gmtime(&now_time));
    struct tm  local    = *(localtime(&now_time));
    int        tzdiff   = 0;

    stamp->data[0] = gsm_int_to_bcdi( local.tm_year % 100 );
    stamp->data[1] = gsm_int_to_bcdi( local.tm_mon+1 );
    stamp->data[2] = gsm_int_to_bcdi( local.tm_mday );
    stamp->data[3] = gsm_int_to_bcdi( local.tm_hour );
    stamp->data[4] = gsm_int_to_bcdi( local.tm_min );
    stamp->data[5] = gsm_int_to_bcdi( local.tm_sec );

    tzdiff = (local.tm_hour*4 + local.tm_min/15) - (gm.tm_hour*4 + gm.tm_min/15);
    if (local.tm_yday > gm.tm_yday)
        tzdiff += 24*4;
    else if (local.tm_yday < gm.tm_yday)
        tzdiff -= 24*4;

    stamp->data[6] = gsm_int_to_bcdi( tzdiff >= 0 ? tzdiff : -tzdiff );
    if (tzdiff < 0)
        stamp->data[6] |= 0x08;
}

int
sms_timestamp_to_tm( SmsTimeStamp  stamp, struct tm*  tm )
{
    int  tzdiff;

    tm->tm_year = gsm_int_from_bcdi( stamp->data[0] );
    if (tm->tm_year < 50)
        tm->tm_year += 100;
    tm->tm_mon  = gsm_int_from_bcdi( stamp->data[1] ) -1;
    tm->tm_mday = gsm_int_from_bcdi( stamp->data[2] );
    tm->tm_hour = gsm_int_from_bcdi( stamp->data[3] );
    tm->tm_min  = gsm_int_from_bcdi( stamp->data[4] );
    tm->tm_sec  = gsm_int_from_bcdi( stamp->data[5] );

    tm->tm_isdst = -1;

    tzdiff = gsm_int_from_bcdi( stamp->data[6] & 0xf7 );
    if (stamp->data[6] & 0x8)
        tzdiff = -tzdiff;

    return tzdiff;
}

static void
gsm_rope_add_timestamp( GsmRope  rope, const SmsTimeStampRec*  ts )
{
    gsm_rope_add( rope, ts->data, 7 );
}


/** SMS ADDRESSES
 **/

int
sms_address_from_str( SmsAddress  address, const char*  src, int  srclen )
{
    const char*  end   = src + srclen;
    int          shift = 0, len = 0;
    bytes_t      data = address->data;

    address->len = 0;
    address->toa = 0x81;

    if (src >= end)
        return -1;

    if ( src[0] == '+' ) {
        address->toa = 0x91;
        if (++src == end)
            goto Fail;
    }

    memset( address->data, 0, sizeof(address->data) );

    shift = 0;

    while (src < end) {
        int  c = *src++ - '0';

        if ( (unsigned)c >= 10 ||
              data >= address->data + sizeof(address->data) )
            goto Fail;

        data[0] |= c << shift;
        len   += 1;
        shift += 4;
        if (shift == 8) {
            shift = 0;
            data += 1;
        }
    }
    if (shift != 0)
        data[0] |= 0xf0;

    address->len = len;
    return 0;

Fail:
    return -1;
}

int
sms_address_to_str( SmsAddress address, char*  str, int  strlen )
{
    static const char  dialdigits[16] = "0123456789*#,N%";
    int                n, count = 0;

    if (address->toa == 0x91) {
        if (count < strlen)
            str[count] = '+';
        count++;
    }
    for (n = 0; n < address->len; n += 2)
    {
        int   c = address->data[n/2];

        if (count < strlen)
            str[count] = dialdigits[c & 0xf];
        count += 1;

        if (n+1 > address->len)
            break;

        if (count < strlen)
            str[count] = dialdigits[(c >> 4) & 0xf];
        if (str[count])
            count += 1;
    }
    return count;
}

int
sms_address_from_bytes( SmsAddress  address, const unsigned char*  buf, int  buflen )
{
    int   len = sizeof(address->data), num_digits;

    if (buflen < 2)
        return -1;

    address->len = num_digits = buf[0];
    address->toa = buf[1];

    len = (num_digits+1)/2;
    if ( len > sizeof(address->data) )
        return -1;

    memcpy( address->data, buf+2, len );
    return 0;
}

int
sms_address_to_bytes( SmsAddress  address, unsigned char*  buf, int  bufsize )
{
    int  len = (address->len + 1)/2 + 2;

    if (buf == NULL)
        bufsize = 0;

    if (bufsize < 1) goto Exit;
    buf[0] = address->len;

    if (bufsize < 2) goto Exit;
    buf[1] = address->toa;

    buf     += 2;
    bufsize -= 2;
    if (bufsize > len-2)
        bufsize = len - 2;

    memcpy( buf, address->data, bufsize );
Exit:
    return len;
}

int
sms_address_from_hex  ( SmsAddress  address, const char*  hex, int  hexlen )
{
    const char*  hexend = hex + hexlen;
    int          nn, len, num_digits;

    if (hexlen < 4)
        return -1;

    address->len = num_digits = gsm_hex2_to_byte( hex );
    address->toa = gsm_hex2_to_byte( hex+2 );
    hex += 4;

    len = (num_digits + 1)/2;
    if (hex + len*2 > hexend)
        return -1;

    for ( nn = 0; nn < len; nn++ )
        address->data[nn] = gsm_hex2_to_byte( hex + nn*2 );

    return 0;
}

int
sms_address_to_hex    ( SmsAddress  address, char*   hex, int  hexlen )
{
    int  len = (address->len + 1)/2 + 2;
    int  nn;

    if (hex == NULL)
        hexlen = 0;

    if (hexlen < 2) goto Exit;
    gsm_hex_from_byte( hex, address->len );
    if (hexlen < 4) goto Exit;
    gsm_hex_from_byte( hex+2, address->toa );
    hex    += 4;
    hexlen -= 4;
    if ( hexlen > 2*(len - 2) )
        hexlen = (len - 2)/2;

    for ( nn = 0; nn < hexlen; nn += 2 )
        gsm_hex_from_byte( hex+nn, address->data[nn/2] );

Exit:
    return len*2;
}

static void
gsm_rope_add_address( GsmRope  rope, const SmsAddressRec*  addr )
{
    gsm_rope_add_c( rope, addr->len );
    gsm_rope_add_c( rope, addr->toa );
    gsm_rope_add( rope, addr->data, (addr->len+1)/2 );
    if (addr->len & 1) {
        if (!rope->error && rope->data != NULL)
            rope->data[ rope->pos-1 ] |= 0xf0;
    }
}

static int
sms_address_eq( const SmsAddressRec*  addr1, const SmsAddressRec*  addr2 )
{
    if ( addr1->toa != addr2->toa ||
         addr1->len != addr2->len )
        return 0;

    return ( !memcmp( addr1->data, addr2->data, addr1->len ) );
}

/** SMS PARSER
 **/
static int
sms_get_byte( cbytes_t  *pcur, cbytes_t  end )
{
    cbytes_t  cur    = *pcur;
    int       result = -1;

    if (cur < end) {
        result = cur[0];
        *pcur  = cur + 1;
    }
    return result;
}

/* parse a service center address, returns -1 in case of error */
static int
sms_get_sc_address( cbytes_t   *pcur,
                    cbytes_t    end,
                    SmsAddress  address )
{
    cbytes_t  cur    = *pcur;
    int       result = -1;

    if (cur < end) {
        int  len = cur[0];
        int  dlen, adjust = 0;

        cur += 1;

        if (len == 0) {   /* empty address */
            address->len = 0;
            address->toa = 0x00;
            result       = 0;
            goto Exit;
        }

        if (cur + len > end) {
            goto Exit;
        }

        address->toa = *cur++;
        len         -= 1;
        result       = 0;

        for (dlen = 0; dlen < len; dlen+=1)
        {
            int  c = cur[dlen];
            int  v;

            adjust = 0;
            if (dlen >= sizeof(address->data)) {
                result = -1;
                break;
            }

            v = (c & 0xf);
            if (v >= 0xe)
                break;

            adjust              = 1;
            address->data[dlen] = (byte_t) c;

            v = (c >> 4) & 0xf;
            if (v >= 0xe) {
                break;
            }
        }
        address->len = 2*dlen + adjust;
    }
Exit:
    if (!result)
        *pcur = cur;

    return result;
}

static int
sms_skip_sc_address( cbytes_t   *pcur,
                     cbytes_t    end )
{
    cbytes_t  cur    = *pcur;
    int       result = -1;
    int       len;

    if (cur >= end)
        goto Exit;

    len  = cur[0];
    cur += 1 + len;
    if (cur > end)
        goto Exit;

    *pcur  = cur;
    result = 0;
Exit:
    return result;
}

/* parse a sender/receiver address, returns -1 in case of error */
static int
sms_get_address( cbytes_t   *pcur,
                 cbytes_t    end,
                 SmsAddress  address )
{
    cbytes_t  cur    = *pcur;
    int       result = -1;
    int       len, dlen;

    if (cur >= end)
        goto Exit;

    dlen = *cur++;

    if (dlen == 0) {
        address->len = 0;
        address->toa = 0;
        result       = 0;
        goto Exit;
    }

    if (cur + 1 + (dlen+1)/2 > end)
        goto Exit;

    address->len = dlen;
    address->toa = *cur++;

    len = (dlen + 1)/2;
    if (len > sizeof(address->data))
        goto Exit;

    memcpy( address->data, cur, len );
    cur   += len;
    result = 0;

Exit:
    if (!result)
        *pcur = cur;

    return result;
}

static int
sms_skip_address( cbytes_t   *pcur,
                  cbytes_t    end  )
{
    cbytes_t  cur    = *pcur;
    int       result = -1;
    int       dlen;

    if (cur + 2 > end)
        goto Exit;

    dlen = cur[0];
    cur += 2 + (dlen + 1)/2;
    if (cur > end)
        goto Exit;

    result = 0;
Exit:
    return result;
}

/* parse a service center timestamp */
static int
sms_get_timestamp( cbytes_t     *pcur,
                   cbytes_t      end,
                   SmsTimeStamp  ts )
{
    cbytes_t  cur = *pcur;

    if (cur + 7 > end)
        return -1;

    memcpy( ts->data, cur, 7 );
    *pcur = cur + 7;
    return 0;
}

static int
sms_skip_timestamp( cbytes_t  *pcur,
                    cbytes_t   end )
{
    cbytes_t  cur = *pcur;

    if (cur + 7 > end)
        return -1;

    *pcur = cur + 7;
    return 0;
}


static int
sms_skip_validity_period( cbytes_t  *pcur,
                          cbytes_t   end,
                          int        mtiByte )
{
    cbytes_t  cur = *pcur;

    switch ((mtiByte >> 3) & 3) {
        case 1:  /* relative format */
            cur += 1;
            break;

        case 2:  /* enhanced format */
        case 3:  /* absolute format */
            cur += 7;
    }
    if (cur > end)
        return -1;

    *pcur = cur;
    return 0;
}

/** SMS PDU
 **/

typedef struct SmsPDURec {
    bytes_t  base;
    bytes_t  end;
    bytes_t  tpdu;
} SmsPDURec;

void
smspdu_free( SmsPDU  pdu )
{
    if (pdu) {
        free( pdu->base );
        pdu->base = NULL;
        pdu->end  = NULL;
        pdu->tpdu = NULL;
    }
}

SmsPduType
smspdu_get_type( SmsPDU  pdu )
{
    cbytes_t  data    = pdu->tpdu;
    cbytes_t  end     = pdu->end;
    int       mtiByte = sms_get_byte(&data, end);

    switch (mtiByte & 3) {
        case 0:  return SMS_PDU_DELIVER;
        case 1:  return SMS_PDU_SUBMIT;
        case 2:  return SMS_PDU_STATUS_REPORT;
        default: return SMS_PDU_INVALID;
    }
}

int
smspdu_get_sender_address( SmsPDU  pdu, SmsAddress  address )
{
    cbytes_t  data    = pdu->tpdu;
    cbytes_t  end     = pdu->end;
    int       mtiByte = sms_get_byte(&data, end);

    switch (mtiByte & 3) {
        case 0: /* SMS_PDU_DELIVER; */
            return sms_get_sc_address( &data, end, address );

        default: return -1;
    }
}

int
smspdu_get_sc_timestamp( SmsPDU  pdu, SmsTimeStamp  ts )
{
    cbytes_t  data    = pdu->tpdu;
    cbytes_t  end     = pdu->end;
    int       mtiByte = sms_get_byte( &data, end );

    switch (mtiByte & 3) {
        case 0:  /* SMS_PDU_DELIVER */
            {
                SmsAddressRec  address;

                if ( sms_get_sc_address( &data, end, &address ) < 0 )
                    return -1;

                data += 2;  /* skip protocol identifer + coding scheme */

                return sms_get_timestamp( &data, end, ts );
            }

        default: return -1;
    }
}

int
smspdu_get_receiver_address( SmsPDU  pdu, SmsAddress  address )
{
    cbytes_t  data    = pdu->tpdu;
    cbytes_t  end     = pdu->end;
    int       mtiByte = sms_get_byte( &data, end );

    switch (mtiByte & 3) {
        case 1:  /* SMS_PDU_SUBMIT */
            {
                data += 1;  /* skip message reference */
                return sms_get_address( &data, end, address );
            }

        default: return -1;
    }
}

typedef enum {
    SMS_CODING_SCHEME_UNKNOWN = 0,
    SMS_CODING_SCHEME_GSM7,
    SMS_CODING_SCHEME_UCS2

} SmsCodingScheme;

/* see TS 23.038 Section 5 for details */
static SmsCodingScheme
sms_get_coding_scheme( cbytes_t  *pcur,
                       cbytes_t   end )
{
    cbytes_t  cur = *pcur;
    int       dataCoding;

    if (cur >= end)
        return SMS_CODING_SCHEME_UNKNOWN;

    dataCoding = *cur++;
    *pcur      = cur;

    switch (dataCoding >> 4) {
        case 0x00:
        case 0x02:
        case 0x03:
            return SMS_CODING_SCHEME_GSM7;

        case 0x01:
            if (dataCoding == 0x10) return SMS_CODING_SCHEME_GSM7;
            if (dataCoding == 0x11) return SMS_CODING_SCHEME_UCS2;
            break;

        case 0x04: case 0x05: case 0x06: case 0x07:
            if (dataCoding & 0x20)           return SMS_CODING_SCHEME_UNKNOWN; /* compressed 7-bits */
            if (((dataCoding >> 2) & 3) == 0) return SMS_CODING_SCHEME_GSM7;
            if (((dataCoding >> 2) & 3) == 2) return SMS_CODING_SCHEME_UCS2;
            break;

        case 0xF:
            if (!(dataCoding & 4)) return SMS_CODING_SCHEME_GSM7;
            break;
    }
    return SMS_CODING_SCHEME_UNKNOWN;
}


/* see TS 23.040 section 9.2.3.24 for details */
static int
sms_get_text_utf8( cbytes_t        *pcur,
                   cbytes_t         end,
                   int              hasUDH,
                   SmsCodingScheme  coding,
                   GsmRope          rope )
{
    cbytes_t  cur    = *pcur;
    int       result = -1;
    int       len;

    if (cur >= end)
        goto Exit;

    len = *cur++;

    /* skip user data header if any */
    if ( hasUDH )
    {
        int  hlen;

        if (cur >= end)
            goto Exit;

        hlen = *cur++;
        if (cur + hlen > end)
            goto Exit;

        cur += hlen;

        if (coding == SMS_CODING_SCHEME_GSM7)
            len -= 2*(hlen+1);
        else
            len -= hlen+1;

        if (len < 0)
            goto Exit;
    }

    /* switch the user data header if any */
    if (coding == SMS_CODING_SCHEME_GSM7)
    {
        int  count = utf8_from_gsm7( cur, 0, len, NULL );

        if (rope != NULL)
        {
            bytes_t  dst = gsm_rope_reserve( rope, count );
            if (dst != NULL)
                utf8_from_gsm7( cur, 0, len, dst );
        }
        cur += (len+1)/2;
    }
    else if (coding == SMS_CODING_SCHEME_UCS2)
    {
        int  count = ucs2_to_utf8( cur, len/2, NULL );

        if (rope != NULL)
        {
            bytes_t  dst = gsm_rope_reserve( rope, count );
            if (dst != NULL)
                ucs2_to_utf8( cur, len/2, dst );
        }
        cur += len;
    }
    result = 0;

Exit:
    if (!result)
        *pcur = cur;

    return result;
}

/* get the message embedded in a SMS PDU as a utf8 byte array, returns the length of the message in bytes */
/* or -1 in case of error */
int
smspdu_get_text_message( SmsPDU  pdu, unsigned char*  utf8, int  utf8len )
{
    cbytes_t  data    = pdu->tpdu;
    cbytes_t  end     = pdu->end;
    int       mtiByte = sms_get_byte( &data, end );

    switch (mtiByte & 3) {
        case 0:  /* SMS_PDU_DELIVER */
            {
                SmsAddressRec    address;
                SmsTimeStampRec  timestamp;
                SmsCodingScheme  coding;
                GsmRopeRec       rope[1];
                int              result;

                if ( sms_get_sc_address( &data, end, &address ) < 0 )
                    goto Fail;

                data  += 1;  /* skip protocol identifier */
                coding = sms_get_coding_scheme( &data, end );
                if (coding == SMS_CODING_SCHEME_UNKNOWN)
                    goto Fail;

                if ( sms_get_timestamp( &data, end, &timestamp ) < 0 )
                    goto Fail;

                if ( sms_get_text_utf8( &data, end, (mtiByte & 0x40), coding, rope ) < 0 )
                    goto Fail;

                result = rope->pos;
                if (utf8len > result)
                    utf8len = result;

                if (utf8len > 0)
                    memcpy( utf8, rope->data, utf8len );

                gsm_rope_done( rope );
                return result;
            }

        case 1:  /* SMS_PDU_SUBMIT */
            {
                SmsAddressRec    address;
                SmsCodingScheme  coding;
                GsmRopeRec       rope[1];
                int              result;

                data += 1;  /* message reference */

                if ( sms_get_address( &data, end, &address ) < 0 )
                    goto Fail;

                data  += 1;  /* skip protocol identifier */
                coding = sms_get_coding_scheme( &data, end );
                if (coding == SMS_CODING_SCHEME_UNKNOWN)
                    goto Fail;

                gsm_rope_init_alloc( rope, 0 );
                if ( sms_get_text_utf8( &data, end, (mtiByte & 0x40), coding, rope ) < 0 ) {
                    gsm_rope_done( rope );
                    goto Fail;
                }

                result = rope->pos;
                if (utf8len > result)
                    utf8len = result;

                if (utf8len > 0)
                    memcpy( utf8, rope->data, utf8len );

                gsm_rope_done( rope );
                return result;
            }
    }
Fail:
    return -1;
}

static cbytes_t
smspdu_get_user_data_ref( SmsPDU  pdu )
{
    cbytes_t  data    = pdu->tpdu;
    cbytes_t  end     = pdu->end;
    int       mtiByte = sms_get_byte( &data, end );
    int       len;

    /* if there is no user-data-header, there is no message reference here */
    if ((mtiByte & 0x40) == 0)
        goto Fail;

    switch (mtiByte & 3) {
        case 0:  /* SMS_PDU_DELIVER */
            if ( sms_skip_address( &data, end ) < 0 )
                goto Fail;

            data  += 2;  /* skip protocol identifier + coding scheme */

            if ( sms_skip_timestamp( &data, end ) < 0 )
                goto Fail;

            break;

        case 1:  /* SMS_PDU_SUBMIT */
            data += 1;  /* skip message reference */

            if ( sms_skip_address( &data, end ) < 0 )
                goto Fail;

            data += 2;  /* protocol identifier + oding schene */
            if ( sms_skip_validity_period( &data, end, mtiByte ) < 0 )
                goto Fail;

            break;

        default:
            goto Fail;
    }

    /* skip user-data length */
    if (data+1 >= end)
        goto Fail;

    len   = data[1];
    data += 2;

    while (len >= 2 && data + 2 <= end) {
        int  htype = data[0];
        int  hlen = data[1];

        if (htype == 00 && hlen == 3 && data + 5 <= end) {
            return data + 2;
        }

        data += hlen;
        len  -= hlen - 2;
    }
Fail:
    return NULL;
}

int
smspdu_get_ref( SmsPDU  pdu )
{
    cbytes_t  user_ref = smspdu_get_user_data_ref( pdu );

    if (user_ref != NULL)
    {
        return user_ref[0];
    }
    else
    {
        cbytes_t  data    = pdu->tpdu;
        cbytes_t  end     = pdu->end;
        int       mtiByte = sms_get_byte( &data, end );

        if ((mtiByte & 3) == 1) {
            /* try to extract directly the reference for a SMS-SUBMIT */
            if (data < end)
                return data[0];
        }
    }
    return -1;
}

int
smspdu_get_max_index( SmsPDU  pdu )
{
    cbytes_t  user_ref = smspdu_get_user_data_ref( pdu );

    if (user_ref != NULL) {
        return user_ref[1];
    } else {
        return 1;
    }
}

int
smspdu_get_cur_index( SmsPDU  pdu )
{
    cbytes_t  user_ref = smspdu_get_user_data_ref( pdu );

    if (user_ref != NULL) {
        return user_ref[2] - 1;
    } else {
        return 0;
    }
}


static void
gsm_rope_add_sms_user_header( GsmRope  rope,
                              int      ref_number,
                              int      pdu_count,
                              int      pdu_index )
{
    gsm_rope_add_c( rope, 0x05 );     /* total header length == 5 bytes */
    gsm_rope_add_c( rope, 0x00 );     /* element id: concatenated message reference number */
    gsm_rope_add_c( rope, 0x03 );     /* element len: 3 bytes */
    gsm_rope_add_c( rope, (byte_t)ref_number );  /* reference number */
    gsm_rope_add_c( rope, (byte_t)pdu_count );     /* max pdu index */
    gsm_rope_add_c( rope, (byte_t)pdu_index+1 );   /* current pdu index */
}

/* write a SMS-DELIVER PDU into a rope */
static void
gsm_rope_add_sms_deliver_pdu( GsmRope                 rope,
                              cbytes_t                utf8,
                              int                     utf8len,
                              int                     use_gsm7,
                              const SmsAddressRec*    sender_address,
                              const SmsTimeStampRec*  timestamp,
                              int                     ref_num,
                              int                     pdu_count,
                              int                     pdu_index)
{
    int  coding;
    int  mtiByte  = 0x20;  /* message type - SMS DELIVER */

    if (pdu_count > 1)
        mtiByte |= 0x40;  /* user data header indicator */

    gsm_rope_add_c( rope, 0 );        /* no SC Address */
    gsm_rope_add_c( rope, mtiByte );     /* message type - SMS-DELIVER */
    gsm_rope_add_address( rope, sender_address );
    gsm_rope_add_c( rope, 0 );        /* protocol identifier */

    /* data coding scheme - GSM 7 bits / no class - or - 16-bit UCS2 / class 1 */
    coding = (use_gsm7 ? 0x00 : 0x09);

    gsm_rope_add_c( rope, coding );               /* data coding scheme       */
    gsm_rope_add_timestamp( rope, timestamp );    /* service center timestamp */

    if (use_gsm7) {
        bytes_t  dst;
        int    count = utf8_to_gsm7( utf8, utf8len, NULL, 0 );
        int    pad   = 0;

        assert( count <= MAX_USER_DATA_SEPTETS - USER_DATA_HEADER_SIZE );

        if (pdu_count > 1)
        {
            int  headerBits    = 6*8;  /* 6 is size of header in bytes */
            int  headerSeptets = headerBits / 7;
            if (headerBits % 7 > 0)
                headerSeptets += 1;

            pad = headerSeptets*7 - headerBits;

            gsm_rope_add_c( rope, count + headerSeptets );
            gsm_rope_add_sms_user_header(rope, ref_num, pdu_count, pdu_index);
        }
        else
            gsm_rope_add_c( rope, count );

        count = (count*7+pad+7)/8;  /* convert to byte count */

        dst = gsm_rope_reserve( rope, count );
        if (dst != NULL) {
            utf8_to_gsm7( utf8, utf8len, dst, pad );
        }
    } else {
        bytes_t  dst;
        int      count = utf8_to_ucs2( utf8, utf8len, NULL );

        assert( count*2 <= MAX_USER_DATA_BYTES - USER_DATA_HEADER_SIZE );

        if (pdu_count > 1)
        {
            gsm_rope_add_c( rope, count*2 + 6 );
            gsm_rope_add_sms_user_header( rope, ref_num, pdu_count, pdu_index );
        }
        else
            gsm_rope_add_c( rope, count*2 );

        dst = gsm_rope_reserve( rope, count*2 );
        if (dst != NULL) {
            utf8_to_ucs2( utf8, utf8len, dst );
        }
    }
}


static SmsPDU
smspdu_create_deliver( cbytes_t               utf8,
                       int                    utf8len,
                       int                    use_gsm7,
                       const SmsAddressRec*   sender_address,
                       const SmsTimeStampRec* timestamp,
                       int                    ref_num,
                       int                    pdu_count,
                       int                    pdu_index )
{
    SmsPDU      p;
    GsmRopeRec  rope[1];
    int         size;

    p = calloc( sizeof(*p), 1 );
    if (!p) goto Exit;

    gsm_rope_init( rope );
    gsm_rope_add_sms_deliver_pdu( rope, utf8, utf8len, use_gsm7,
                                 sender_address, timestamp,
                                 ref_num, pdu_count, pdu_index);
    if (rope->error)
        goto Fail;

    gsm_rope_init_alloc( rope, rope->pos );

    gsm_rope_add_sms_deliver_pdu( rope, utf8, utf8len, use_gsm7,
                                 sender_address, timestamp,
                                 ref_num, pdu_count, pdu_index );

    p->base = gsm_rope_done_acquire( rope, &size );
    if (p->base == NULL)
        goto Fail;

    p->end  = p->base + size;
    p->tpdu = p->base + 1;
Exit:
    return p;

Fail:
    free(p);
    return NULL;
}


void
smspdu_free_list( SmsPDU*  pdus )
{
    if (pdus) {
        int  nn;
        for (nn = 0; pdus[nn] != NULL; nn++)
            smspdu_free( pdus[nn] );

        free( pdus );
    }
}



SmsPDU*
smspdu_create_deliver_utf8( const unsigned char*   utf8,
                            int                    utf8len,
                            const SmsAddressRec*   sender_address,
                            const SmsTimeStampRec* timestamp )
{
    SmsTimeStampRec  ts0;
    int              use_gsm7;
    int              count, block;
    int              num_pdus = 0;
    int              leftover = 0;
    SmsPDU*          list = NULL;

    static unsigned char  ref_num = 0;

    if (timestamp == NULL) {
        sms_timestamp_now( &ts0 );
        timestamp = &ts0;
    }

    /* can we encode the message with the GSM 7-bit alphabet ? */
    use_gsm7 = utf8_check_gsm7( utf8, utf8len );

    /* count the number of SMS PDUs we'll need */

    if (use_gsm7) {
        count = utf8_to_gsm7( utf8, utf8len, NULL, 0 );
        block = MAX_USER_DATA_SEPTETS - USER_DATA_HEADER_SIZE;
        num_pdus = count / block;
        leftover = count - num_pdus*block;
    } else {
        count = utf8_to_ucs2( utf8, utf8len, NULL );
        block = MAX_USER_DATA_BYTES - USER_DATA_HEADER_SIZE;
        num_pdus = (2 * count) / block;
        leftover = (2 * count) - num_pdus*block;
    }

    if (leftover > 0)
        num_pdus += 1;

    list = calloc( sizeof(SmsPDU*), num_pdus + 1 );
    if (list == NULL)
        return NULL;

    /* now create each SMS PDU */
    {
        cbytes_t   src     = utf8;
        cbytes_t   src_end = utf8 + utf8len;
        int        nn;

        for (nn = 0; nn < num_pdus; nn++)
        {
            int       skip = block;
            cbytes_t  src_next;

            if (leftover > 0 && nn == num_pdus-1)
                skip = leftover;

            /* How many utf8 symbols will fit in this PDU? */
            if (use_gsm7) {
                src_next = utf8_skip_gsm7( src, src_end, skip );
            } else {
                src_next = utf8_skip_ucs2( src, src_end, skip );
            }

            list[nn] = smspdu_create_deliver( src, src_next - src, use_gsm7, sender_address, timestamp,
                                              ref_num, num_pdus, nn );
            if (list[nn] == NULL)
                goto Fail;

            src = src_next;
        }
    }

    ref_num++;
    return list;

Fail:
    smspdu_free_list(list);
    return NULL;
}


SmsPDU
smspdu_create_from_hex( const char*  hex, int  hexlen )
{
    SmsPDU    p;
    cbytes_t  data;

    p = calloc( sizeof(*p), 1 );
    if (!p) goto Exit;

    p->base = malloc( (hexlen+1)/2 );
    if (p->base == NULL) {
        free(p);
        p = NULL;
        goto Exit;
    }

    if ( gsm_hex_to_bytes( (cbytes_t)hex, hexlen, p->base ) < 0 )
        goto Fail;

    p->end = p->base + (hexlen+1)/2;

    data = p->base;
    if ( sms_skip_sc_address( &data, p->end ) < 0 )
        goto Fail;

    p->tpdu = (bytes_t) data;

Exit:
    return p;

Fail:
    free(p->base);
    free(p);
    return NULL;
}

int
smspdu_to_hex( SmsPDU  pdu, char*  hex, int  hexlen )
{
    int  result = (pdu->end - pdu->base)*2;
    int  nn;

    if (hexlen > result)
        hexlen = result;

    for (nn = 0; nn*2 < hexlen; nn++) {
        gsm_hex_from_byte( &hex[nn*2], pdu->base[nn] );
    }
    return result;
}


/** SMS SUBMIT RECEIVER
 ** collects one or more SMS-SUBMIT PDUs to generate a single message to deliver
 **/

typedef struct SmsFragmentRec {
    struct SmsFragmentRec*  next;
    SmsAddressRec           from[1];
    byte_t                  ref;
    byte_t                  max;
    byte_t                  count;
    int                     index;
    SmsPDU*                 pdus;

} SmsFragmentRec, *SmsFragment;


typedef struct SmsReceiverRec {
    int           last;
    SmsFragment   fragments;

} SmsReceiverRec;


static void
sms_fragment_free( SmsFragment  frag )
{
    int  nn;

    for (nn = 0; nn < frag->max; nn++) {
        if (frag->pdus[nn] != NULL) {
            smspdu_free( frag->pdus[nn] );
            frag->pdus[nn] = NULL;
        }
    }
    frag->pdus  = NULL;
    frag->count = 0;
    frag->max   = 0;
    frag->index = 0;
    free( frag );
}

static SmsFragment
sms_fragment_alloc( SmsReceiver  rec, const SmsAddressRec*  from, int   ref, int  max )
{
    SmsFragment  frag = calloc(sizeof(*frag) + max*sizeof(SmsPDU), 1 );

    if (frag != NULL) {
        frag->from[0] = from[0];
        frag->ref     = ref;
        frag->max     = max;
        frag->pdus    = (SmsPDU*)(frag + 1);
        frag->index   = ++rec->last;
    }
    return  frag;
}



SmsReceiver   sms_receiver_create( void )
{
    SmsReceiver  rec = calloc(sizeof(*rec),1);
    return rec;
}

void
sms_receiver_destroy( SmsReceiver  rec )
{
    while (rec->fragments) {
        SmsFragment  frag = rec->fragments;
        rec->fragments = frag->next;
        sms_fragment_free(frag);
    }
}

static SmsFragment*
sms_receiver_find_p( SmsReceiver  rec, const SmsAddressRec*  from, int  ref )
{
    SmsFragment*  pnode = &rec->fragments;
    SmsFragment   node;

    for (;;) {
        node = *pnode;
        if (node == NULL)
            break;
        if (node->ref == ref && sms_address_eq( node->from, from ))
            break;
        pnode = &node->next;
    }
    return  pnode;
}

static SmsFragment*
sms_receiver_find_index_p( SmsReceiver  rec, int  index )
{
    SmsFragment*  pnode = &rec->fragments;
    SmsFragment   node;

    for (;;) {
        node = *pnode;
        if (node == NULL)
            break;
        if (node->index == index)
            break;
        pnode = &node->next;
    }
    return  pnode;
}

int
sms_receiver_add_submit_pdu( SmsReceiver  rec, SmsPDU       submit_pdu )
{
    SmsAddressRec  from[1];
    int            ref, max, cur;
    SmsFragment*   pnode;
    SmsFragment    frag;

    if ( smspdu_get_receiver_address( submit_pdu, from ) < 0 ) {
        D( "%s: could not extract receiver address\n", __FUNCTION__ );
        return -1;
    }

    ref = smspdu_get_ref( submit_pdu );
    if (ref < 0) {
        D( "%s: could not extract message reference from pdu\n", __FUNCTION__ );
        return -1;
    }
    max = smspdu_get_max_index( submit_pdu );
    if (max < 0) {
        D( "%s: invalid max fragment value: %d should be >= 1\n",
           __FUNCTION__, max );
        return -1;
    }
    pnode = sms_receiver_find_p( rec, from, ref );
    frag  = *pnode;
    if (frag == NULL) {
        frag = sms_fragment_alloc( rec, from, ref, max );
        if (frag == NULL) {
            D("%s: not enough memory to allocate new fragment\n", __FUNCTION__ );
            return -1;
        }
        if (D_ACTIVE) {
            char  tmp[32];
            int   len;

            len = sms_address_to_str( from, tmp, sizeof(tmp) );
            if (len < 0) {
                strcpy( tmp, "<unknown>" );
                len = strlen(tmp);
            }
            D("%s: created SMS index %d, from %.*s, ref %d, max %d\n", __FUNCTION__,
               frag->index, len, tmp, frag->ref, frag->max);
        }
        *pnode = frag;
    }

    cur = smspdu_get_cur_index( submit_pdu );
    if (cur < 0) {
        D("%s: SMS fragment index is too small: %d should be >= 1\n", __FUNCTION__, cur+1 );
        return -1;
    }
    if (cur >= max) {
        D("%s: SMS fragment index is too large (%d >= %d)\n", __FUNCTION__, cur, max);
        return -1;
    }
    if ( frag->pdus[cur] != NULL ) {
        D("%s: receiving duplicate SMS fragment for %d/%d, ref=%d, discarding old one\n",
          __FUNCTION__, cur+1, max, ref);
        smspdu_free( frag->pdus[cur] );
        frag->count -= 1;
    }
    frag->pdus[cur] = submit_pdu;
    frag->count    += 1;

    if (frag->count >= frag->max) {
        /* yes, we received all fragments for this SMS */
        D( "%s: SMS index %d, received all %d fragments\n", __FUNCTION__, frag->index, frag->count );
        return frag->index;
    }
    else {
        /* still waiting for more */
        D( "%s: SMS index %d, received %d/%d, waiting for %d more\n", __FUNCTION__,
            frag->index, cur+1, max, frag->max - frag->count );
        return 0;
    }
}


int
sms_receiver_get_text_message( SmsReceiver  rec, int  index, bytes_t  utf8, int  utf8len )
{
    SmsFragment*  pnode = sms_receiver_find_index_p( rec, index );
    SmsFragment   frag  = *pnode;
    int           nn, total;

    if (frag == NULL) {
        D( "%s: invalid SMS index %d\n", __FUNCTION__, index );
        return -1;
    }
    if (frag->count != frag->max) {
        D( "%s: SMS index %d still needs %d fragments\n", __FUNCTION__,
           frag->index, frag->max - frag->count );
        return -1;
    }
    /* get the size of all combined text */
    total = 0;
    for ( nn = 0; nn < frag->count; nn++ ) {
        int  partial;
        if (utf8 && utf8len > 0) {
            partial  = smspdu_get_text_message( frag->pdus[nn], utf8, utf8len );
            utf8    += partial;
            utf8len -= partial;
        } else {
            partial  = smspdu_get_text_message( frag->pdus[nn], NULL, 0 );
        }
        total += partial;
    }
    return total;
}


static void
sms_receiver_remove( SmsReceiver  rec, int  index )
{
    SmsFragment*  pnode = sms_receiver_find_index_p( rec, index );
    SmsFragment   frag  = *pnode;
    if (frag != NULL) {
        *pnode = frag->next;
        sms_fragment_free(frag);
    }
}


SmsPDU*
sms_receiver_create_deliver( SmsReceiver  rec, int  index, const SmsAddressRec*  from )
{
    SmsPDU*          result = NULL;
    SmsFragment*     pnode = sms_receiver_find_index_p( rec, index );
    SmsFragment      frag  = *pnode;
    SmsTimeStampRec  now[1];
    int              nn, total;
    bytes_t          utf8;
    int              utf8len;

    if (frag == NULL) {
        D( "%s: invalid SMS index %d\n", __FUNCTION__, index );
        return NULL;
    }
    if (frag->count != frag->max) {
        D( "%s: SMS index %d still needs %d fragments\n", __FUNCTION__,
           frag->index, frag->max - frag->count );
        return NULL;
    }

    /* get the combined text message */
    utf8len = sms_receiver_get_text_message( rec, index, NULL, 0 );
    if (utf8len < 0)
        goto Exit;

    utf8 = malloc( utf8len + 1 );
    if (utf8 == NULL) {
        D( "%s: not enough memory to allocate %d bytes\n",
           __FUNCTION__, utf8len+1 );
        goto Exit;
    }

    total = 0;
    for ( nn = 0; nn < frag->count; nn++ ) {
        total += smspdu_get_text_message( frag->pdus[nn], utf8 + total, utf8len - total );
    }

    sms_timestamp_now( now );

    result = smspdu_create_deliver_utf8( utf8, utf8len, from, now );

    free(utf8);

Exit:
    sms_receiver_remove( rec, index );
    return result;
}

