hal: Add API to set & get audio calibration

added base64 encode and decode utility functions
Add API to set & get audio calibration.
Use audiocal for set & get key.

Change-Id: I2ea3362a75bd99018f404d8cf0771efa0a2aabf7
diff --git a/hal/audio_extn/utils.c b/hal/audio_extn/utils.c
index 8bd98a0..a9b9a0d 100644
--- a/hal/audio_extn/utils.c
+++ b/hal/audio_extn/utils.c
@@ -48,6 +48,9 @@
 #define STRING_TO_ENUM(string) { #string, string }
 #define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0]))
 
+#define BASE_TABLE_SIZE 64
+#define MAX_BASEINDEX_LEN 256
+
 struct string_to_enum {
     const char *name;
     uint32_t value;
@@ -97,6 +100,15 @@
 #endif
 };
 
+static char bTable[BASE_TABLE_SIZE] = {
+            'A','B','C','D','E','F','G','H','I','J','K','L',
+            'M','N','O','P','Q','R','S','T','U','V','W','X',
+            'Y','Z','a','b','c','d','e','f','g','h','i','j',
+            'k','l','m','n','o','p','q','r','s','t','u','v',
+            'w','x','y','z','0','1','2','3','4','5','6','7',
+            '8','9','+','/'
+};
+
 static uint32_t string_to_enum(const struct string_to_enum *table, size_t size,
                                const char *name)
 {
@@ -567,3 +579,145 @@
     }
 }
 
+// Base64 Encode and Decode
+// Not all features supported. This must be used only with following conditions.
+// Decode Modes: Support with and without padding
+//         CRLF not handling. So no CRLF in string to decode.
+// Encode Modes: Supports only padding
+int b64decode(char *inp, int ilen, uint8_t* outp)
+{
+    int i, j, k, ii, num;
+    int rem, pcnt;
+    uint32_t res=0;
+    uint8_t getIndex[MAX_BASEINDEX_LEN];
+    uint8_t tmp, cflag;
+
+    if(inp == NULL || outp == NULL || ilen <= 0) {
+        ALOGE("[%s] received NULL pointer or zero length",__func__);
+        return -1;
+    }
+
+    memset(getIndex, MAX_BASEINDEX_LEN-1, sizeof(getIndex));
+    for(i=0;i<BASE_TABLE_SIZE;i++) {
+        getIndex[(uint8_t)bTable[i]] = (uint8_t)i;
+    }
+    getIndex[(uint8_t)'=']=0;
+
+    j=0;k=0;
+    num = ilen/4;
+    rem = ilen%4;
+    if(rem==0)
+        num = num-1;
+    cflag=0;
+    for(i=0; i<num; i++) {
+        res=0;
+        for(ii=0;ii<4;ii++) {
+            res = res << 6;
+            tmp = getIndex[(uint8_t)inp[j++]];
+            res = res | tmp;
+            cflag = cflag | tmp;
+        }
+        outp[k++] = (res >> 16)&0xFF;
+        outp[k++] = (res >> 8)&0xFF;
+        outp[k++] = res & 0xFF;
+    }
+
+    // Handle last bytes special
+    pcnt=0;
+    if(rem == 0) {
+        //With padding or full data
+        res = 0;
+        for(ii=0;ii<4;ii++) {
+            if(inp[j] == '=')
+                pcnt++;
+            res = res << 6;
+            tmp = getIndex[(uint8_t)inp[j++]];
+            res = res | tmp;
+            cflag = cflag | tmp;
+        }
+        outp[k++] = res >> 16;
+        if(pcnt == 2)
+            goto done;
+        outp[k++] = (res>>8)&0xFF;
+        if(pcnt == 1)
+            goto done;
+        outp[k++] = res&0xFF;
+    } else {
+        //without padding
+        res = 0;
+        for(i=0;i<rem;i++) {
+            res = res << 6;
+            tmp = getIndex[(uint8_t)inp[j++]];
+            res = res | tmp;
+            cflag = cflag | tmp;
+        }
+        for(i=rem;i<4;i++) {
+            res = res << 6;
+            pcnt++;
+        }
+        outp[k++] = res >> 16;
+        if(pcnt == 2)
+            goto done;
+        outp[k++] = (res>>8)&0xFF;
+        if(pcnt == 1)
+            goto done;
+        outp[k++] = res&0xFF;
+    }
+done:
+    if(cflag == 0xFF) {
+        ALOGE("[%s] base64 decode failed. Invalid character found %s",
+            __func__, inp);
+        return 0;
+    }
+    return k;
+}
+
+int b64encode(uint8_t *inp, int ilen, char* outp)
+{
+    int i,j,k, num;
+    int rem=0;
+    uint32_t res=0;
+
+    if(inp == NULL || outp == NULL || ilen<=0) {
+        ALOGE("[%s] received NULL pointer or zero input length",__func__);
+        return -1;
+    }
+
+    num = ilen/3;
+    rem = ilen%3;
+    j=0;k=0;
+    for(i=0; i<num; i++) {
+        //prepare index
+        res = inp[j++]<<16;
+        res = res | inp[j++]<<8;
+        res = res | inp[j++];
+        //get output map from index
+        outp[k++] = (char) bTable[(res>>18)&0x3F];
+        outp[k++] = (char) bTable[(res>>12)&0x3F];
+        outp[k++] = (char) bTable[(res>>6)&0x3F];
+        outp[k++] = (char) bTable[res&0x3F];
+    }
+
+    switch(rem) {
+        case 1:
+            res = inp[j++]<<16;
+            outp[k++] = (char) bTable[res>>18];
+            outp[k++] = (char) bTable[(res>>12)&0x3F];
+            //outp[k++] = '=';
+            //outp[k++] = '=';
+            break;
+        case 2:
+            res = inp[j++]<<16;
+            res = res | inp[j++]<<8;
+            outp[k++] = (char) bTable[res>>18];
+            outp[k++] = (char) bTable[(res>>12)&0x3F];
+            outp[k++] = (char) bTable[(res>>6)&0x3F];
+            //outp[k++] = '=';
+            break;
+        default:
+            break;
+    }
+done:
+    outp[k] = '\0';
+    return k;
+}