String to Dynamic Byte array
Common C-string to byte array functions as shown in https://stackoverflow.com/questions/3408706/hexadecimal-string-to-byte-array-in-c work perfectly fine. 

Source hex string: 6D616320747820636E662031352033300D0A
Conversion OK buff 0x289 len 18
output byte array:
  00 6d 61 63 20 74 78 20 63 6e 66 20 31 35 20 33 30  mac tx cnf 15 30
  10 0d 0a                                            ..


#include &lt;Arduino.h&gt;

void hexDump (const char *desc, const void *addr, const int len);

bool convert_hexstr_to_bytearray(const char* source, uint8_t* &amp;output,
        size_t&amp; output_len) {
    size_t len = strlen(source);
    //cannot convert non-even string length
    if ((len % 2) != 0) {
        return false;
    }
    //dynamically allocate output buffer
    output_len = len / 2;
    output = (uint8_t*) malloc(output_len);
    const char* curPos = source;
    for (size_t count = 0; count &lt; len; count++) {
        sscanf(curPos, "%2hhx", output + count);
        curPos += 2;
    }
    return true;
}

String Finalval="6D616320747820636E662031352033300D0A";

void setup() {
    Serial.begin(115200);
    Serial.print("Source hex string: ");
    Serial.println(Finalval);
    Serial.flush();

    uint8_t* buffer = nullptr;
    size_t buffer_len = 0;
    if(convert_hexstr_to_bytearray(Finalval.c_str(), buffer, buffer_len)) {
        Serial.println("Conversion OK buff 0x" + String((long)buffer,HEX) + " len " + String(buffer_len));
        hexDump("output byte array", buffer, buffer_len);
    } else {
        Serial.println("Conversion failed\n");
    }

    //free memory
    if(buffer)
        free(buffer);
}

void loop() {
}

void PrintHex8(const uint8_t *data, uint8_t length) // prints 8-bit data in hex
{
     char tmp[length*2+1];
     byte first;
     byte second;
     for (int i=0; i&lt;length; i++) {
           first = (data[i] &gt;&gt; 4) &amp; 0x0f;
           second = data[i] &amp; 0x0f;
           // base for converting single digit numbers to ASCII is 48
           // base for 10-16 to become lower-case characters a-f is 87
           // note: difference is 39
           tmp[i*2] = first+48;
           tmp[i*2+1] = second+48;
           if (first &gt; 9) tmp[i*2] += 39;
           if (second &gt; 9) tmp[i*2+1] += 39;
     }
     tmp[length*2] = 0;
     Serial.print(tmp);
}

void hexDump (const char *desc, const void *addr, const int len) {
    int i;
    unsigned char buff[17];
    const unsigned char *pc = (const unsigned char*)addr;

    // Output description if given.
    if (desc != NULL) {
        Serial.print (desc);
        Serial.println(":");
    }

    if (len == 0) {
        Serial.print("  ZERO LENGTH\n");
        return;
    }
    if (len &lt; 0) {
        Serial.println("  NEGATIVE LENGTH: " + String(len));
        return;
    }

    // Process every byte in the data.
    for (i = 0; i &lt; len; i++) {
        // Multiple of 16 means new line (with line offset).

        if ((i % 16) == 0) {
            // Just don't print ASCII for the zeroth line.
            if (i != 0) {
                Serial.print ("  ");
                Serial.println((char*)buff);
            }

            // Output the offset.
            Serial.print ("  ");
            PrintHex8((uint8_t*)&amp;i, 1);
        }

        // Now the hex code for the specific character.
        Serial.print(" ");
        PrintHex8(pc + i,1);


        // And store a printable ASCII character for later.
        if ((pc[i] &lt; 0x20) || (pc[i] &gt; 0x7e))
            buff[i % 16] = '.';
        else
            buff[i % 16] = pc[i];
        buff[(i % 16) + 1] = '\0';
    }

    // Pad out last line if not exactly 16 characters.
    while ((i % 16) != 0) {
        Serial.print ("   ");
        i++;
    }

    // And print the final ASCII bit.
    Serial.print ("  ");
    Serial.println((char*)buff);
}