SDP client for myBlueUSB

Dependents:   mbed_TANK_Kinect ftusbClass

sdp_data.cpp

Committer:
networker
Date:
2011-04-04
Revision:
0:7493bf6bb1b9
Child:
2:d5a27b2d2e08

File content as of revision 0:7493bf6bb1b9:

#include "mbed.h"
#include "sdp_data.h"

char sdp_data::ret[12];

unsigned sdp_data::asUnsigned() {
    switch (type) {
        case NULL_:
            return 0;
        case UNSIGNED:
        case SIGNED:
        case BOOL:
            return data;
        case UUID:
#ifdef LONGUUID
            return uuid[6] + uuid[7]<<16;
#else
            return data;
#endif
        default:
            return 0;
    }
}

const char* sdp_data::asString(bool alt) {
    char sep = ',';
    switch (type) {
        case NULL_:
            return "NULL";
        case UNSIGNED:
            if (alt) sprintf(ret, "0x%0*X", size*2, data);
            else sprintf(ret, "%u", data);
            return ret;
        case SIGNED:
            sprintf(ret, "%d", data);
            return ret;
        case BOOL:
            return data ? "TRUE" : "FALSE";
        case STRING:
        case URL:
            return str;
        case ALTERNATIVE:
            sep = '|';
        case SEQUENCE: {
            if (longstr) delete[] longstr;
            int n = sprintf(ret, "SEQ %d { ", size) + 1;
            longstr = new char[n];
            strcpy(longstr, ret);
            for (int i = 0; i < sequence.size(); i++) {
                const char *s = sequence[i]->asString(alt);
                n = strlen(longstr) + strlen(s) + 2;
                char *t = new char[n];
                strcpy(t, longstr);
                strcat(t, s);
                t[n-2] = sep;
                t[n-1]='\0';
                //printf("[%s]+[%s]+%c=[%s]\n", longstr, s, sep, t);
                delete[] longstr;
                longstr = t;
            }
            longstr[n-2] = '}';
        }
        return longstr;
        case UUID:
#ifdef LONGUUID
            switch (size) {
                case 2:
                    sprintf(ret, "0x%04X", uuid[6]);
                    return ret;
                case 4:
                    sprintf(ret, "0x%04X%04X", uuid[7],uuid[6]);
                    return ret;
                case 16:
                    longstr = new char[35];
                    sprintf(longstr, "%04X%04X-%04X-%04X-%04X-%04X%04X%04X", uuid[7],uuid[6],uuid[5],uuid[4],uuid[3],uuid[2],uuid[1],uuid[0]);
                    return longstr;
            }
#else
            switch (size) {
                case 2:
                    sprintf(ret, "0x%04X", data & 0xffff);
                    return ret;
                case 4:
                    sprintf(ret, "0x%08X", data);
                    return ret;
                case 16:
                    longstr = new char[35];
                    sprintf(longstr, "%08X-%04X-%04X-%04X-%04X%04X%04X", data,base_uuid[5],base_uuid[4],base_uuid[3],base_uuid[2],base_uuid[1],base_uuid[0]);
                    return longstr;
            }
#endif
    }
    return "Unsupported";
}

unsigned sdp_data::Size() {
    if (size<3 || size==4 || size==8 || size==16)
        return size+1;//include descriptor
    if (size < 256) return size+2; //1 extra byte
    if (size < 65536) return size+3; //2 extra bytes
    return size+5; //4 extra bytes
}

unsigned sdp_data::sizedesc(unsigned char *buf) {
    int desc, extra=0;
    switch (size) {
        case 0:
        case 1:
            desc = 0;
            break;
        case 2:
            desc = 1;
            break;
        case 4:
            desc = 2;
            break;
        case 8:
            desc = 3;
            break;
        case 16:
            desc = 4;
            break;
        default:
            if (size < 256) {
                desc = 5;
                extra = 1;
                buf[1] = size;
            } else if (size < 65536) {
                desc = 6;
                extra = 2;
                *(unsigned short*)&buf[1] = size;
            } else {
                desc = 7;
                extra = 4;
                *(unsigned*)&buf[1] = size;
            }
    }
    buf[0] |= desc;
    return extra+1;
}

void sdp_data::revcpy(unsigned char*d, const unsigned char*s, int n) {
    for (int i = 0; i < n; i++)
        d[i] = s[n-i-1];
}

unsigned sdp_data::build(unsigned char *buf, unsigned max) {
    int p = 0;
    if (size+5 < max) {
        buf[p] = type<<3;
        switch (type) {
            case NULL_:
                p++;
                break;
            case UNSIGNED:
            case SIGNED:
            case BOOL:
                p += sizedesc(buf+p);
                revcpy(buf+p, (unsigned char*)&data, size);
                break;
            case UUID:
                p += sizedesc(buf+p);
#ifdef LONGUUID
                switch (size) {
                    case 2:
                    case 4:
                        revcpy(buf+p, (unsigned char*)&uuid[6], size);
                        break;
                    case 16:
                        revcpy(buf+p, (unsigned char*)uuid, size);
                        break;
                }
#else
                switch (size) {
                    case 2:
                    case 4:
                        revcpy(buf+p, (unsigned char*)&data, size);
                        break;
                    case 16:
                        revcpy(buf+p, (unsigned char*)&data, 4);
                        revcpy(buf+p+4, base_uuid, 12);
                        break;
                }
#endif
                break;
            case STRING:
            case URL:
                p += sizedesc(buf+p);
                memcpy(buf+p, str, size);
                break;
            case SEQUENCE:
            case ALTERNATIVE:
                p += sizedesc(buf+p);
                for (int i = 0; i < sequence.size(); i++)
                    sequence.at(i)->build(buf+p, max-p);
                break;
        }
        p += size;
    } else { //too big, make continuation
        printf ("Data too large to fit\n");
    }
    return p;
}