diff --git a/lib/modem-commands.js b/lib/modem-commands.js
deleted file mode 100644
index 763201e..0000000
--- a/lib/modem-commands.js
+++ /dev/null
@@ -1,170 +0,0 @@
-const MUTEX_COMMAND = 'COMMAND';
-exports.MUTEX_COMMAND = MUTEX_COMMAND;
-
-const MUTEX_SUBCOMMAND = 'SUBCOMMAND';
-exports.MUTEX_SUBCOMMAND = MUTEX_SUBCOMMAND;
-
-const ParserReadline = require('@serialport/parser-readline');
-const ParserRegex = require('@serialport/parser-regex');
-
-const logger = require('komodo-sdk/logger');
-const mutex = require('./mutex-common');
-const parsers = require('./serialport-parsers');
-const modemInfo = require('./modem-info');
-
-let port;
-
-function writeToPort(data) {
-    return new Promise((resolve) => {
-        modemInfo.lastWriteTs = new Date();
-        port.write(data, (err, bytesWritten) => {
-            if (err) logger.warn(`ERROR: ${err.toString()}`);
-
-            logger.verbose('OUTGOING', { data: data.toString(), bytesWritten, err });
-            resolve(bytesWritten);
-        });
-    });
-}
-
-exports.writeToPortAndWaitForReadline = function writeToPortAndWaitForReadline(cmd, lockName) {
-    let resolved = false;
-
-    return new Promise(async (resolve) => {
-        const parser = new ParserReadline({ delimiter: parsers.PARSER_READLINE_DELIMITER });
-        parser.on('data', (data) => {
-            port.unpipe(parser);
-            mutex.unlock(lockName || MUTEX_COMMAND, cmd.trim());
-            if (!resolved) {
-                resolved = true;
-                resolve(data);
-            }
-        });
-
-        await mutex.lock(lockName || MUTEX_COMMAND, cmd.trim());
-        port.pipe(parser);
-        await writeToPort(cmd);
-    });
-};
-
-exports.writeToPortAndWaitForOkOrError = function writeToPortAndWaitForOkOrError(cmd, lockName) {
-    return new Promise(async (resolve) => {
-        const parser = new ParserRegex({ regex: /(?:OK|ERROR)\r\n/ });
-        parser.on('data', (data) => {
-            port.unpipe(parser);
-            mutex.unlock(lockName || MUTEX_COMMAND, cmd.trim());
-            resolve(data);
-        });
-
-        await mutex.lock(lockName || MUTEX_COMMAND, cmd.trim());
-        port.pipe(parser);
-        await writeToPort(cmd);
-    });
-};
-
-exports.sleep = function sleep(ms) {
-    return new Promise((resolve) => {
-        setTimeout(() => {
-            resolve();
-        }, ms || 0);
-    });
-};
-
-
-exports.setPort = function setPort(val) {
-    port = val;
-};
-
-exports.querySignalQuality = function querySignalQuality() {
-    return new Promise(async (resolve) => {
-        if (!mutex.tryLock(MUTEX_COMMAND, 'querySignalQuality')) {
-            resolve(false);
-            return;
-        }
-
-        await writeToPort('AT+CSQ\r');
-        mutex.unlock(MUTEX_COMMAND, 'querySignalQuality');
-        resolve(true);
-    });
-};
-
-exports.queryCOPS = function queryCOPS(lockName) {
-    return new Promise(async (resolve) => {
-        await mutex.lock(lockName || MUTEX_COMMAND, 'queryCOPS');
-        await writeToPort('AT+COPS?\r');
-        mutex.unlock(lockName || MUTEX_COMMAND, 'queryCOPS');
-        resolve(true);
-    });
-};
-
-exports.queryCOPSAndSignalQuality = function queryCOPSAndSignalQuality(skipOnLocked) {
-    return new Promise(async (resolve) => {
-        if (!skipOnLocked) {
-            await mutex.lock(MUTEX_COMMAND);
-        } else if (!mutex.tryLock(MUTEX_COMMAND, 'queryCOPSAndSignalQuality')) {
-            resolve(false);
-            return;
-        }
-
-        await this.writeToPortAndWaitForOkOrError('AT+COPS?\r', MUTEX_SUBCOMMAND);
-        await this.writeToPortAndWaitForOkOrError('AT+CSQ\r', MUTEX_SUBCOMMAND);
-
-        mutex.unlock(MUTEX_COMMAND, 'queryCopsAndSignalQuality');
-        resolve(true);
-    });
-};
-
-exports.queryIMEI = function queryIMEI(lockName) {
-    return new Promise(async (resolve) => {
-        const parser = new ParserRegex({ regex: parsers.PARSER_WAIT_FOR_OK_OR_ERROR_REGEX });
-        parser.on('data', (data) => {
-            logger.verbose('INCOMING', { data: data.toString(), parser: 'parserIMEI' });
-            port.unpipe(parser);
-            mutex.unlock(lockName || MUTEX_COMMAND, 'queryIMEI');
-            modemInfo.imei = data.toString().trim() || null;
-            logger.info('IMEI extracted', { imei: modemInfo.imei });
-            resolve(modemInfo.imei);
-        });
-
-        await mutex.lock(lockName || MUTEX_COMMAND, 'queryIMEI');
-
-        port.pipe(parser);
-        await writeToPort('AT+CGSN\r');
-    });
-};
-
-exports.queryIMSI = function queryIMSI(lockName) {
-    return new Promise(async (resolve) => {
-        const parser = new ParserRegex({ regex: parsers.PARSER_WAIT_FOR_OK_OR_ERROR_REGEX });
-        parser.on('data', (data) => {
-            logger.verbose('INCOMING', { data: data.toString(), parser: 'parserIMSI' });
-            port.unpipe(parser);
-            mutex.unlock(lockName || MUTEX_COMMAND, 'queryIMSI');
-            modemInfo.imsi = data.toString().trim() || null;
-            logger.info('IMSI extracted', { imsi: modemInfo.imsi });
-            resolve(modemInfo.imsi);
-        });
-
-        await mutex.lock(lockName || MUTEX_COMMAND, 'queryIMSI');
-
-        port.pipe(parser);
-        await writeToPort('AT+CIMI\r');
-    });
-};
-
-exports.queryIMEIAndIMSI = async function queryIMEIAndIMSI() {
-    await mutex.lock(MUTEX_COMMAND, 'queryIMEIAndIMSI');
-
-    const imei = await this.queryIMEI(MUTEX_SUBCOMMAND);
-    const imsi = await this.queryIMSI(MUTEX_SUBCOMMAND);
-
-    await mutex.unlock(MUTEX_COMMAND, 'queryIMEIAndIMSI');
-    return { imei, imsi };
-};
-
-exports.initATCommands = async function initATCommands() {
-    await mutex.lock(MUTEX_COMMAND, 'INIT MODEM');
-    await this.writeToPortAndWaitForOkOrError('ATE0\r', MUTEX_SUBCOMMAND);
-    await this.writeToPortAndWaitForOkOrError('AT+CMGF=0\r', MUTEX_SUBCOMMAND);
-    await this.writeToPortAndWaitForOkOrError('AT+CNMI=1,2,0,1,0\r', MUTEX_SUBCOMMAND);
-    mutex.unlock(MUTEX_COMMAND, 'INIT MODEM');
-};
diff --git a/lib/modem-commands/index.js b/lib/modem-commands/index.js
new file mode 100644
index 0000000..2d15a77
--- /dev/null
+++ b/lib/modem-commands/index.js
@@ -0,0 +1,216 @@
+const MUTEX_COMMAND = 'COMMAND';
+exports.MUTEX_COMMAND = MUTEX_COMMAND;
+
+const MUTEX_SUBCOMMAND = 'SUBCOMMAND';
+exports.MUTEX_SUBCOMMAND = MUTEX_SUBCOMMAND;
+
+const pdu = require('node-pdu');
+
+const ParserReadline = require('@serialport/parser-readline');
+const ParserRegex = require('@serialport/parser-regex');
+
+const logger = require('komodo-sdk/logger');
+const mutex = require('../mutex-common');
+const parsers = require('../serialport-parsers');
+const modemInfo = require('../modem-info');
+
+let port;
+
+function writeToPort(data) {
+    return new Promise((resolve) => {
+        modemInfo.lastWriteTs = new Date();
+        port.write(data, (err, bytesWritten) => {
+            if (err) logger.warn(`ERROR: ${err.toString()}`);
+
+            logger.verbose('OUTGOING', { data: data.toString(), bytesWritten, err });
+            resolve(bytesWritten);
+        });
+    });
+}
+
+exports.writeToPortAndWaitForReadline = function writeToPortAndWaitForReadline(cmd, lockName) {
+    let resolved = false;
+
+    return new Promise(async (resolve) => {
+        const parser = new ParserReadline({ delimiter: parsers.PARSER_READLINE_DELIMITER });
+        parser.on('data', (data) => {
+            port.unpipe(parser);
+            mutex.unlock(lockName || MUTEX_COMMAND, cmd.trim());
+            if (!resolved) {
+                resolved = true;
+                resolve(data);
+            }
+        });
+
+        await mutex.lock(lockName || MUTEX_COMMAND, cmd.trim());
+        port.pipe(parser);
+        await writeToPort(cmd);
+    });
+};
+
+exports.writeToPortAndWaitForOkOrError = function writeToPortAndWaitForOkOrError(cmd, lockName) {
+    return new Promise(async (resolve) => {
+        const parser = new ParserRegex({ regex: /(?:OK|ERROR)\r\n/ });
+        parser.on('data', (data) => {
+            port.unpipe(parser);
+            mutex.unlock(lockName || MUTEX_COMMAND, cmd.trim());
+            resolve(data);
+        });
+
+        await mutex.lock(lockName || MUTEX_COMMAND, cmd.trim());
+        port.pipe(parser);
+        await writeToPort(cmd);
+    });
+};
+
+exports.sleep = function sleep(ms) {
+    return new Promise((resolve) => {
+        setTimeout(() => {
+            resolve();
+        }, ms || 0);
+    });
+};
+
+
+exports.setPort = function setPort(val) {
+    port = val;
+};
+
+exports.querySignalQuality = function querySignalQuality() {
+    return new Promise(async (resolve) => {
+        if (!mutex.tryLock(MUTEX_COMMAND, 'querySignalQuality')) {
+            resolve(false);
+            return;
+        }
+
+        await writeToPort('AT+CSQ\r');
+        mutex.unlock(MUTEX_COMMAND, 'querySignalQuality');
+        resolve(true);
+    });
+};
+
+exports.queryCOPS = function queryCOPS(lockName) {
+    return new Promise(async (resolve) => {
+        await mutex.lock(lockName || MUTEX_COMMAND, 'queryCOPS');
+        await writeToPort('AT+COPS?\r');
+        mutex.unlock(lockName || MUTEX_COMMAND, 'queryCOPS');
+        resolve(true);
+    });
+};
+
+exports.queryCOPSAndSignalQuality = function queryCOPSAndSignalQuality(skipOnLocked) {
+    return new Promise(async (resolve) => {
+        if (!skipOnLocked) {
+            await mutex.lock(MUTEX_COMMAND);
+        } else if (!mutex.tryLock(MUTEX_COMMAND, 'queryCOPSAndSignalQuality')) {
+            resolve(false);
+            return;
+        }
+
+        await this.writeToPortAndWaitForOkOrError('AT+COPS?\r', MUTEX_SUBCOMMAND);
+        await this.writeToPortAndWaitForOkOrError('AT+CSQ\r', MUTEX_SUBCOMMAND);
+
+        mutex.unlock(MUTEX_COMMAND, 'queryCopsAndSignalQuality');
+        resolve(true);
+    });
+};
+
+exports.queryIMEI = function queryIMEI(lockName) {
+    return new Promise(async (resolve) => {
+        const parser = new ParserRegex({ regex: parsers.PARSER_WAIT_FOR_OK_OR_ERROR_REGEX });
+        parser.on('data', (data) => {
+            logger.verbose('INCOMING', { data: data.toString(), parser: 'parserIMEI' });
+            port.unpipe(parser);
+            mutex.unlock(lockName || MUTEX_COMMAND, 'queryIMEI');
+            modemInfo.imei = data.toString().trim() || null;
+            logger.info('IMEI extracted', { imei: modemInfo.imei });
+            resolve(modemInfo.imei);
+        });
+
+        await mutex.lock(lockName || MUTEX_COMMAND, 'queryIMEI');
+
+        port.pipe(parser);
+        await writeToPort('AT+CGSN\r');
+    });
+};
+
+exports.queryIMSI = function queryIMSI(lockName) {
+    return new Promise(async (resolve) => {
+        const parser = new ParserRegex({ regex: parsers.PARSER_WAIT_FOR_OK_OR_ERROR_REGEX });
+        parser.on('data', (data) => {
+            logger.verbose('INCOMING', { data: data.toString(), parser: 'parserIMSI' });
+            port.unpipe(parser);
+            mutex.unlock(lockName || MUTEX_COMMAND, 'queryIMSI');
+            modemInfo.imsi = data.toString().trim() || null;
+            logger.info('IMSI extracted', { imsi: modemInfo.imsi });
+            resolve(modemInfo.imsi);
+        });
+
+        await mutex.lock(lockName || MUTEX_COMMAND, 'queryIMSI');
+
+        port.pipe(parser);
+        await writeToPort('AT+CIMI\r');
+    });
+};
+
+exports.queryIMEIAndIMSI = async function queryIMEIAndIMSI() {
+    await mutex.lock(MUTEX_COMMAND, 'queryIMEIAndIMSI');
+
+    const imei = await this.queryIMEI(MUTEX_SUBCOMMAND);
+    const imsi = await this.queryIMSI(MUTEX_SUBCOMMAND);
+
+    await mutex.unlock(MUTEX_COMMAND, 'queryIMEIAndIMSI');
+    return { imei, imsi };
+};
+
+exports.queryManufacturer = function queryManufacturer(lockName) {
+    return new Promise(async (resolve) => {
+        const parser = new ParserRegex({ regex: parsers.PARSER_WAIT_FOR_OK_OR_ERROR_REGEX });
+        parser.on('data', (data) => {
+            logger.verbose('INCOMING', { data: data.toString(), parser: 'parserManufacturer' });
+            port.unpipe(parser);
+            mutex.unlock(lockName || MUTEX_COMMAND, 'parserManufacturer');
+            modemInfo.manufacturer = data.toString().trim() || null;
+            logger.info('Manufacturer extracted', { manufacturer: modemInfo.manufacturer });
+            resolve(modemInfo.manufacturer);
+        });
+
+        await mutex.lock(lockName || MUTEX_COMMAND, 'queryManufacturer');
+
+        port.pipe(parser);
+        await writeToPort('AT+CGMI\r');
+    });
+};
+
+exports.queryModel = function queryModel(lockName) {
+    return new Promise(async (resolve) => {
+        const parser = new ParserRegex({ regex: parsers.PARSER_WAIT_FOR_OK_OR_ERROR_REGEX });
+        parser.on('data', (data) => {
+            logger.verbose('INCOMING', { data: data.toString(), parser: 'parserModel' });
+            port.unpipe(parser);
+            mutex.unlock(lockName || MUTEX_COMMAND, 'parserModel');
+            modemInfo.model = data.toString().trim() || null;
+            logger.info('Model extracted', { model: modemInfo.model });
+            resolve(modemInfo.model);
+        });
+
+        await mutex.lock(lockName || MUTEX_COMMAND, 'queryModel');
+
+        port.pipe(parser);
+        await writeToPort('AT+CGMM\r');
+    });
+};
+
+exports.sendSMS = function sendSMS(destination, msg) {
+    return new Promise(async (resolve) => {
+        
+    });
+};
+
+exports.initATCommands = async function initATCommands() {
+    await mutex.lock(MUTEX_COMMAND, 'INIT MODEM');
+    await this.writeToPortAndWaitForOkOrError('\rATE0\r', MUTEX_SUBCOMMAND);
+    await this.writeToPortAndWaitForOkOrError('AT+CMGF=0\r', MUTEX_SUBCOMMAND);
+    await this.writeToPortAndWaitForOkOrError('AT+CNMI=1,2,0,1,0\r', MUTEX_SUBCOMMAND);
+    mutex.unlock(MUTEX_COMMAND, 'INIT MODEM');
+};
diff --git a/modem-tester.js b/modem-tester.js
index df61a89..87b0b36 100644
--- a/modem-tester.js
+++ b/modem-tester.js
@@ -20,23 +20,29 @@ const port = new SerialPort(config.modem.device, { baudRate: 115200 }, async (er
         process.exit(1);
     }
 
-    await modemCommands.writeToPortAndWaitForOkOrError('AT\r');
+    await modemCommands.writeToPortAndWaitForOkOrError('\rAT\r');
     await modemCommands.writeToPortAndWaitForOkOrError('AT&FE0\r');
     await modemCommands.writeToPortAndWaitForOkOrError('AT+CMGF=0\r');
     await modemCommands.writeToPortAndWaitForOkOrError('AT+CNMI=1,2,0,1,0\r');
 
+    await modemCommands.queryManufacturer();
+    await modemCommands.queryModel();
+
     await modemCommands.queryIMEIAndIMSI();
     await modemCommands.queryCOPSAndSignalQuality();
     logger.info('Modem state', modemInfo);
 
     setInterval(async () => {
         await modemCommands.initATCommands();
+        await modemCommands.queryManufacturer();
+        await modemCommands.queryModel();
         await modemCommands.queryIMEIAndIMSI();
         await modemCommands.queryCOPSAndSignalQuality();
         logger.info('Modem state', modemInfo);
     }, (config && config.interval_beetwen_signal_strength_ms) || 30000);
 });
 
+global.MODEM_PORT = port;
 parsers.setPort(port);
 modemCommands.setPort(port);