summaryrefslogblamecommitdiffstats
path: root/assets/js/rootLantiq.js
blob: 570133c50fe7ebf4e70135ca18f180ec0b558eed (plain) (tree)
1
2
3
4
5
6
7
8
9


                                    
 
                                    



                                                    
                   



         










                                                                                                                                       
















                                                                                          
                                                                     







                                                                                           
                                                                                                           



















                                                    
 
                                                                                                           
                                                                
 
         


                                                                                                                   
                           
                                                                                                                                                                                                        

                     
                                                                             




















                                                                                                                                   

         

                                                                                                 

                                                     
                                                                                                 
                     


     
                                                                                                   
                                                                

         
                                                                                                                 


                                                            







                                                                                                                                                    

                                                                                                 

                                                     
                                                                                                 
                     
     
 




















































































































                                                                                                                                                                                              
const LOAD_ADDR = "80800000"
const IMAGE0_ADDR = "C0000 740000";
const IMAGE1_ADDR = "800000 800000";

async function detectUboot(reader) {
    while (true) {
        const { value, done } = await reader.read();

        if (value.startsWith('U-Boot')) {
            return;
        }
    }
}

async function waitUbootStop(writer, reader, sfpModel, outputMsgCallback) {
    const interval = setInterval(function() {
        writer.write(String.fromCharCode(3));
    }, 10);

    await detectUboot(reader);
    outputMsgCallback(`Root in progress: Trigger characters received. DO NOT TOUCH THE ${sfpModel} UNTIL THE PROCEDURE IS COMPLETED!`);
    await delay(5000);
    clearInterval(interval);
}

async function checkUbootUnlocked(reader) {
    while (true) {
        try {
            const { value, done } = await Promise.race([
                reader.read(),
                new Promise((_, reject) => setTimeout(reject, 2000, new Error("timeout")))
            ]);

            if (value.startsWith('Press SPACE to delay and Ctrl-C to abort autoboot')) {
                return true;
            }
        } catch (err) {
            return false;
        }
    }
}

async function waitFailbackShell(writer, reader, outputMsgCallback) {
    while (true) {
        const { value, done } = await reader.read();

        if (value.startsWith('Press the [f] key and hit [enter] to enter failsafe mode')) {
            const interval = setInterval(function() {
                writer.write('f\n');
            }, 10);

            outputMsgCallback("Root in progress: Trigger characters received. Waiting for boot to end...");
            await delay(3000);
            clearInterval(interval);
            break;
        }
    }

    const interval = setInterval(function() {
        writer.write(String.fromCharCode(10));
    }, 10);

    while (true) {
        const { value, done } = await reader.read();

        if (value.includes('root@(none)')) {
            await delay(1000);
            clearInterval(interval);
            break;
        }
    }
}

async function lantiqRootUboot(port, sfpModel, outputMsgCallback, outputErrorCallback, baudRate = 115200) {
    let reader,writer, readableStreamClosed, writerStreamClosed;

    try {
        outputMsgCallback(`Please disconnect the ${sfpModel} from the SFP adapter if it is currently plugged in!`);
        ({ reader, writer, readableStreamClosed, writerStreamClosed } = await openPortLineBreak(port, baudRate));

        await delay(10000);
        outputMsgCallback(`Now you need to insert the ${sfpModel} into the SFP adapter, if the procedure does not go ahead, check the connections and then remove and reconnect the ${sfpModel} again`);

        while(true) {
            await waitUbootStop(writer, reader, sfpModel, outputMsgCallback);
            const ubootUnlocked = await checkUbootUnlocked(reader);

            if (ubootUnlocked == true) {
                break;
            }

            outputMsgCallback("Root in progress: Set U-Boot bootdelay to 5...");
            writer.write('setenv bootdelay 5\n');
            await delay(1000);
            outputMsgCallback("Root in progress: Enable ASC serial...");
            writer.write('setenv asc0 0\n');
            await delay(1000);
            outputMsgCallback("Root in progress: Set GPIO to unlock serial...");
            writer.write('setenv preboot "gpio set 3;gpio input 2;gpio input 105;gpio input 106;gpio input 107;gpio input 108"\n');
            await delay(1000);
            outputMsgCallback("Root in progress: Save changes...");
            writer.write('saveenv\n');
            await delay(1000);
            outputMsgCallback("Root in progress: Rebooting...");
            writer.write('reset\n');
            await delay(1000);
        }

        await closePortLineBreak(port, reader, writer, readableStreamClosed, writerStreamClosed);
        return true;
    } catch (err) {
        outputErrorCallback(`Error: ${err.message}`);
        await closePortLineBreak(port, reader, writer, readableStreamClosed, writerStreamClosed);
        return false;
    }
}

async function unlockHuaweiShell(port, outputMsgCallback, outputErrorCallback, baudRate = 115200) {
    let reader,writer, readableStreamClosed, writerStreamClosed;

    try {
        ({ reader, writer, readableStreamClosed, writerStreamClosed } = await openPortLineBreak(port, baudRate));
        outputMsgCallback("Root in progress: Rebooting...");
        writer.write('reset\n');
        await delay(1000);
        outputMsgCallback("Waiting for reboot");
        await waitFailbackShell(writer, reader, outputMsgCallback);
        outputMsgCallback("Root in progress: Enable full Linux shell...");
        writer.write('mount_root && mkdir -p /overlay/etc && sed "s|/opt/lantiq/bin/minishell|/bin/ash|g" /rom/etc/passwd > /overlay/etc/passwd\n');
        await delay(1000);
        outputMsgCallback("Root in progress: Umount rootfs partitions...");
        writer.write('umount /overlay && umount -a\n');
        await delay(1000);
        await closePortLineBreak(port, reader, writer, readableStreamClosed, writerStreamClosed);
        return true;
    } catch (err) {
        outputErrorCallback(`Error: ${err.message}`);
        await closePortLineBreak(port, reader, writer, readableStreamClosed, writerStreamClosed);
        return false;
    }
}

async function changeBaudrate(port, newBaudrate, currBaudrate, outputErrorCallback) {
    let reader,writer, readableStreamClosed, writerStreamClosed;

    try {
        ({ reader, writer, readableStreamClosed, writerStreamClosed } = await openPortLineBreak(port, currBaudrate));
        await writer.write(`setenv baudrate ${newBaudrate}\n`);
        await delay(1000);
        await closePortLineBreak(port, reader, writer, readableStreamClosed, writerStreamClosed);
        ({ reader, writer, readableStreamClosed, writerStreamClosed } = await openPortLineBreak(port, newBaudrate));

        const interval = setInterval(function() {
            writer.write(String.fromCharCode(13));
        }, 10);

        while (true) {
            const { value, done } = await reader.read();

            if (value.startsWith('FALCON')) {
                clearInterval(interval);
                break;
            }
        }

        await closePortLineBreak(port, reader, writer, readableStreamClosed, writerStreamClosed);
        return true;
    } catch (err) {
        outputErrorCallback(`Error: ${err.message}`);
        await closePortLineBreak(port, reader, writer, readableStreamClosed, writerStreamClosed);
        return false;
    }
}

async function sendImageMtd(port, data, baudRate, outputErrorCallback, progressCallback) {
    let reader,writer, readableStreamClosed, writerStreamClosed;

    try {
        ({ reader, writer, readableStreamClosed, writerStreamClosed } = await openPortLineBreak(port, baudRate));
        await writer.write(`loady 0x${LOAD_ADDR}\n`);
        await delay(1000);
        await closePortLineBreak(port, reader, writer, readableStreamClosed, writerStreamClosed);   /* XYMini needs reopen the port */
    } catch (err) {
        outputErrorCallback(`Error: ${err.message}`);
        await closePortLineBreak(port, reader, writer, readableStreamClosed, writerStreamClosed);
        return false;
    }

    try {
        await port.open({ baudRate: baudRate });
        reader = port.readable.getReader();
        writer = port.writable.getWriter();

        await sendXYMini(reader, writer, data, baudRate,
            (byteTransfered) => {
                progressCallback(byteTransfered);
            }
        );
        await reader.cancel();
        await writer.close();
        await port.close();
        return true;
    } catch (err) {
        await reader.cancel();
        await writer.close();
        await port.close();
        outputErrorCallback(`Error: ${err.message}`);
        return false;
    }
}

async function waitEndImageLoad(port, baudRate, outputErrorCallback) {
    let reader, writer, readableStreamClosed, writerStreamClosed;

    try {
        ({ reader, writer, readableStreamClosed, writerStreamClosed } = await openPortLineBreak(port, baudRate));

        while (true) {
            const { value, done } = await reader.read();

            if (value.includes('Total Size')) {
                break;
            }
        }

        await(1000);
        await closePortLineBreak(port, reader, writer, readableStreamClosed, writerStreamClosed);
        return true;
    } catch (err) {
        outputErrorCallback(`Error: ${err.message}`);
        await closePortLineBreak(port, reader, writer, readableStreamClosed, writerStreamClosed);
        return false;
    }
}

async function flashImageMtd(port, image, baudRate, outputErrorCallback) {
    let reader, writer, readableStreamClosed, writerStreamClosed;

    try {
        ({ reader, writer, readableStreamClosed, writerStreamClosed } = await openPortLineBreak(port, baudRate));
        if (image == "image0") {
            await writer.write(`sf probe 0 && sf erase ${IMAGE0_ADDR} && sf write ${LOAD_ADDR} ${IMAGE0_ADDR} && setenv committed_image 0 && setenv image0_is_valid 1 && saveenv && reset\n`);
        } else {
            await writer.write(`sf probe 0 && sf erase ${IMAGE1_ADDR} && sf write ${LOAD_ADDR} ${IMAGE1_ADDR} && setenv committed_image 1 && setenv image1_is_valid 1 && saveenv && reset\n`);
        }

        await delay(1000);

        /* Wait to avoid the user from disconnecting the SFP while the image is being flashed */
        await detectUboot(reader);
        await closePortLineBreak(port, reader, writer, readableStreamClosed, writerStreamClosed);
        return true;
    } catch (err) {
        outputErrorCallback(`Error: ${err.message}`);
        await closePortLineBreak(port, reader, writer, readableStreamClosed, writerStreamClosed);
        return false;
    }
}