diff --git a/lib/modems.js b/lib/modems.js
index 8f3ebc8..4a0c68a 100644
--- a/lib/modems.js
+++ b/lib/modems.js
@@ -25,6 +25,52 @@ exports.outgoingModems = (arrayOfModem) => {
     return modems.filter((modem) => modem.outgoing);
 };
 
+exports.OUTGOING_MODEMS = this.outgoingModems();
+
+exports.prefixes = (arrayOfModem) => {
+    const prefixModemsObject = {};
+    const prefixModemsArray = [];
+
+    const modems = this.outgoingModems(arrayOfModem);
+    modems.forEach((modem) => {
+        const modemPrefixes = modem.prefix || [];
+        modemPrefixes.forEach((prefix) => {
+            const normalizedPrefix = prefix.trim().replace(/^0/, '62');
+
+            if (!prefixModemsObject[normalizedPrefix]) {
+                prefixModemsObject[normalizedPrefix] = [modem.name];
+            } else {
+                prefixModemsObject[normalizedPrefix].push(modem.name);
+            }
+        });
+    });
+
+    // eslint-disable-next-line no-restricted-syntax
+    for (const [prefix, value] of Object.entries(prefixModemsObject)) {
+        prefixModemsArray.push({ prefix, modems: value });
+    }
+
+    const retval = prefixModemsArray.sort((a, b) => {
+        if (a.prefix.length < b.prefix.length) return 1;
+        if (a.prefix.length > b.prefix.length) return -1;
+
+        if (a < b) return -1;
+        if (a > b) return 1;
+        return 0;
+    });
+
+    retval.forEach((item) => {
+        // eslint-disable-next-line no-param-reassign
+        item.modems = item.modems.sort((a, b) => {
+            if (a < b) return -1;
+            if (a > b) return 1;
+            return 0;
+        });
+    });
+
+    return retval;
+};
+
 exports.randomModem = (arrayOfModem) => {
     const modems = this.outgoingModems(arrayOfModem);
 
@@ -40,3 +86,29 @@ exports.randomModem = (arrayOfModem) => {
     const idx = Math.floor(Math.random() * modemCount);
     return modems[idx];
 };
+
+exports.findPrefixForNumber = (number, prefixes) => prefixes.find(
+    (item) => number.replace(/^0/, '62').indexOf(item.prefix) === 0,
+);
+
+exports.isFreePrefixModem = (modem) => !modem.prefix || !modem.prefix.length;
+
+exports.randomModemByPrefix = (number, arrayOfModem) => {
+    const modems = this.outgoingModems(arrayOfModem);
+    const prefixes = this.prefixes(arrayOfModem);
+    const prefix = this.findPrefixForNumber(number, prefixes);
+    const modemNamesForPrefix = (prefix || {}).modems;
+
+    if (modemNamesForPrefix && modemNamesForPrefix.length) {
+        const count = modemNamesForPrefix.length;
+        const idx = Math.floor(Math.random() * count);
+        const modemName = modemNamesForPrefix[idx];
+
+        return modems.find((modem) => modem.name === modemName);
+    }
+
+    const freeModems = modems.filter((modem) => this.isFreePrefixModem(modem));
+    const count = freeModems.length;
+    const idx = Math.floor(Math.random() * count);
+    return freeModems[idx];
+};
diff --git a/test/modems.js b/test/modems.js
index 9a4eeb3..5a25866 100644
--- a/test/modems.js
+++ b/test/modems.js
@@ -1,20 +1,211 @@
+/* eslint-disable no-console */
 /* global describe it */
 const modems = require('../lib/modems');
 
-require('should');
+const should = require('should');
 
 describe('#modems', () => {
     describe('#enabledModems', () => {
-        const test1 = modems.enabledModems([
+        it('should return correctly', () => {
+            const test1 = modems.enabledModems([
+                {
+                    name: 'SENDER-AS13',
+                    disabled: false,
+                    outgoing: true,
+                    imsi: null,
+                    prefix: [],
+                },
+            ]);
+
+            test1.should.ok();
+        });
+    });
+
+    describe('#prefixes', () => {
+        it('should return correctly', () => {
+            const config = [
+                {
+                    name: 'XL1',
+                    outgoing: true,
+                    prefix: ['0818', '081'],
+                },
+                {
+                    name: 'TSEL1',
+                    outgoing: true,
+                    prefix: ['0812', '0811'],
+                },
+                {
+                    name: 'TSEL2',
+                    outgoing: true,
+                    prefix: ['0812', '0811'],
+                },
+                {
+                    name: 'ISAT1',
+                    outgoing: true,
+                    prefix: ['0815', '0816'],
+                },
+            ];
+
+            const prefixes = modems.prefixes(config);
+
+            prefixes[0].prefix.should.equal('62811');
+            prefixes[1].prefix.should.equal('62812');
+            prefixes[2].prefix.should.equal('62815');
+            prefixes[3].prefix.should.equal('62816');
+            prefixes[4].prefix.should.equal('62818');
+            prefixes[5].prefix.should.equal('6281');
+
+            prefixes[0].modems[0].should.equal('TSEL1');
+            prefixes[0].modems[1].should.equal('TSEL2');
+            prefixes[1].modems[0].should.equal('TSEL1');
+            prefixes[1].modems[1].should.equal('TSEL2');
+            prefixes[2].modems[0].should.equal('ISAT1');
+            prefixes[3].modems[0].should.equal('ISAT1');
+            prefixes[4].modems[0].should.equal('XL1');
+            prefixes[5].modems[0].should.equal('XL1');
+        });
+    });
+
+    describe('#findPrefixForNumber', () => {
+        it('should return correct prefix', () => {
+            const config = [
+                {
+                    name: 'XL1',
+                    outgoing: true,
+                    prefix: ['0818', '081'],
+                },
+                {
+                    name: 'TSEL1',
+                    outgoing: true,
+                    prefix: ['0812', '0811'],
+                },
+                {
+                    name: 'TSEL2',
+                    outgoing: true,
+                    prefix: ['0812', '0811'],
+                },
+                {
+                    name: 'ISAT1',
+                    outgoing: true,
+                    prefix: ['0815', '0816'],
+                },
+                {
+                    name: 'FREE1',
+                    outgoing: true,
+                    prefix: [],
+                },
+                {
+                    name: 'FREE2',
+                    outgoing: true,
+                    prefix: [],
+                },
+            ];
+
+            const prefixes = modems.prefixes(config);
+            modems.findPrefixForNumber('628188188', prefixes).prefix.should.equal('62818');
+            modems.findPrefixForNumber('08188188', prefixes).prefix.should.equal('62818');
+            modems.findPrefixForNumber('62812812', prefixes).prefix.should.equal('62812');
+            modems.findPrefixForNumber('62810810', prefixes).prefix.should.equal('6281');
+            should.not.exists(modems.findPrefixForNumber('6221212121', prefixes));
+        });
+    });
+
+    describe('#randomModemByPrefix', () => {
+        const config = [
+            {
+                name: 'XL1',
+                outgoing: true,
+                prefix: ['0818', '081'],
+            },
+            {
+                name: 'TSEL1',
+                outgoing: true,
+                prefix: ['0812', '0811'],
+            },
             {
-                name: 'SENDER-AS13',
-                disabled: false,
+                name: 'TSEL2',
+                outgoing: true,
+                prefix: ['0812', '0811'],
+            },
+            {
+                name: 'ISAT1',
+                outgoing: true,
+                prefix: ['0815', '0816'],
+            },
+            {
+                name: 'FREE1',
+                outgoing: true,
+                prefix: [],
+            },
+            {
+                name: 'FREE2',
                 outgoing: true,
-                imsi: null,
                 prefix: [],
             },
-        ]);
+        ];
+
+        const loopCount = 100;
+
+        it('should return correctly for XL', () => {
+            for (let i = 0; i < loopCount; i += 1) {
+                modems.randomModemByPrefix('6281881818', config).name.should.equal('XL1');
+            }
+        });
+
+        it('should return correctly for TSEL', () => {
+            for (let i = 0; i < loopCount; i += 1) {
+                modems.randomModemByPrefix('62812812', config).name.should.equalOneOf('TSEL1', 'TSEL2');
+            }
+        });
+
+        it('should return correctly for INDOSAT', () => {
+            for (let i = 0; i < loopCount; i += 1) {
+                modems.randomModemByPrefix('62815815', config).name.should.equal('ISAT1');
+            }
+        });
+
+        it('should return correctly for UNKNOWN PREFIX', () => {
+            for (let i = 0; i < loopCount; i += 1) {
+                modems.randomModemByPrefix('628888888', config).name.should.equalOneOf('FREE1', 'FREE2');
+            }
+        });
+
+        it('should handle UNKNOWN PREFIX without free modem', () => {
+            // eslint-disable-next-line no-shadow
+            const config = [
+                {
+                    name: 'XL1',
+                    outgoing: true,
+                    prefix: ['0818', '081'],
+                },
+                {
+                    name: 'TSEL1',
+                    outgoing: true,
+                    prefix: ['0812', '0811'],
+                },
+                {
+                    name: 'TSEL2',
+                    outgoing: true,
+                    prefix: ['0812', '0811'],
+                },
+                {
+                    name: 'ISAT1',
+                    outgoing: true,
+                    prefix: ['0815', '0816'],
+                },
+                {
+                    name: 'FREE1',
+                    outgoing: false,
+                    prefix: [],
+                },
+                {
+                    name: 'FREE2',
+                    outgoing: false,
+                    prefix: [],
+                },
+            ];
 
-        test1.should.ok();
+            should.not.exists(modems.randomModemByPrefix('628888888', config));
+        });
     });
 });