Modification of the Doorhan GSM barrier module for control via the Internet



    Recently it was decided to install in the apartment building a barrier controlled via GSM. The reasons and necessity of this decision are beyond the scope of the article, but I want to write about how “on the knee” I made an interface for controlling the module via the Internet. And even a bit with blackjack, managing the base of cars from a mobile phone and photos of the moments of entry from a street camera. Perhaps someone wants to introduce in themselves.

    I will warn you that the article does not describe the out-of-the-box solution, but rather proof of concept.

    Part 1. Why such a controller


    Before you put the GSM-module was carried out some review of the market for such systems. I wanted to get an inexpensive, reliable and proven solution. Well, so that "in the presence of" the installers had, had some experience working with him, etc.

    Installers offered a choice of either ESIM 110/120 for ~ 12000r with Internet access, or Doorhan GSM for ~ 6000r with control via SMS or setting via USB-lace.

    The option "to make your device from the arduino + gsm module for $ 3" ​​was not considered, so the solution should be exactly reliable and run-in. Imagine someone could not come home? Then get the trouble in full.

    I also did not want a lottery with the purchase of a device in China on Ali , again in order to avoid problems with reliability. Although prices start at 1500r.

    The downside of ESIM120, in addition to the cost of x2, was that GPRS-Internet was used to access the Internet. For some, this may be a plus, but in our case it will drag out the cost of mobile communication - we will have to take a tariff with the Internet. Now, on the SIM card, the tariff is connected without a subscription fee, and in order for the number not to be blocked, I plan to connect every 2-3 months from the operator’s personal account a paid subscription for 2-3 rubles per day, for one day. For example, “weather”, “jokes” or whatever else is useful for a barrier)

    About Doorhan GSM, I knew that in addition to controlling via SMS (not very interesting), it is connected via USB to a computer and allows you to manage the base of numbers through your own software.

    Part 2. Forwarding control


    Since the barrier control unit was planned to be installed 20 meters from the room where the house IP video recorder and the local Internet service provider communication center is located, it was decided to take Doorhan and “boost” USB via a router like TP-Link MR3020 1200r, OpenWRT and programs from the USBIP project .

    With the router it was even somewhat simpler - I found an old ASUS WL500gP in the bins, which is not very suitable for the Internet by today's standards, but it has 2 USB ports. He used it.

    For usbip, we had to install an old version of OpenWRT, 12.09, because this kernel module does not work on new ones. I will not describe the connection of the router to the network. If someone has it not in the local network, options with port forwarding, UPNP or VPN settings are possible, to your taste.

    Install kmod-usbip-server and check that we can export

    root@OpenWrt:~# opkg install kmod-usbip-server
    root@OpenWrt:~# usbip list -l
    Local USB devices
    =================
     - busid 1-1 (0424:2502)
             1-1:1.0 -> hub
     - busid 1-1.1 (1a86:7523)
             1-1.1:1.0 -> ch341
    

    We need a busid device, 1-1.1 where our connected GSM controller is located. Looking ahead, it turned out that this is a banal COM-> USB converter on the CH341 chip. We do

    :

    root@OpenWrt:~#usbipd -D
    root@OpenWrt:~#usbip bind -b 1-1.1
    bind device on busid 1-1.1: complete
    

    and in dmesg

     usbip-host 1-1.1:1.0: usbip-host: register new device (bus 1 dev 57 ifn 0)
    

    On a Windows PC, install the USBIP drivers and run

    usbip -a 10.16.19.191-1.1

    where is 10.16.19.19 IP-address of our router with OpenWRT. Of course, first you need to open access either from your IP to the router in the firewall, or connect from the local network, or any of 1000 other options from VPN to P2P.

    If everything went well, then Windows happily declares that a new USB-to-Serial Converter CH340 device has been detected, we are giving it a driver, and a COM port appears in the system.

    Now we can run the program from the kit with the controller and manage the numbers in the database while sitting at home on the couch



    Part 3. Control of entries


    After setting up the work with the controller on the home computer and recording the numbers of the users, I decided to dig deeper with what is available on the COM port.

    It turns out that the GSM module of the controller periodically sends AT commands with the signal level to the console, and also writes the phone number from which the call comes from when making a call. I could not manage the AT module with commands, apparently they are not transmitted from the controller module to the modem module.



    It's pretty interesting anyway. When developing the idea of ​​a GSM controller, I hoped that these calls would be recorded in the operator’s details. But since the connection does not occur, there are no details in the details. Now you can directly from the controller to collect the logs of the one who opened the barrier. Or who tried to do it.

    To do this, install kmod-usb-serial-ch341 on OpenWRT, disable the USBIP translation with the usbip unbind -b 1-1.1 command and do insmod ch341.

    After that, directly on the router, you can connect to / dev / ttyUSB0 and watch what happens there with calls in the controller.

    To process the data, first I wrote a simple script engine that, with the help of curl, sent the data about the incoming call to an external PHP server for processing and saving to the database. With the same success, you can write to a local file, though the memory router is not thick.

    #!/bin/sh
    cat /dev/ttyUSB0 | whileread DATA; doifecho$DATA | grep -q CLIP ; then
      curl --silent --output /dev/null --data "data=$DATA" http://1.2.3.4:8081/border.php
     fidone

    On the server I created a database in mysql and a couple of tablets: with the phone numbers of our tenants, and with the call log. It became possible to compare who at what time opened the barrier, and whether they are trying to use it from unknown numbers.

    The second idea that occurred to me was to make a bundle between the event of opening the barrier and the photo of this event. The thing is, as I mentioned above, there are AHD cameras around the house that write to the recorder with access to the stream via IP. Moreover, one of the chambers was specially turned on the barrier, in anticipation that it would be broken.

    How to remove the jpeg from our Chinese registrar I could not find, although many cameras have a Preview URL. Therefore, I went to the forehead - at the time of the call, I receive the RTSP and make it JPG.

    ffmpeg -i "rtsp://2.3.4.5:554/user=user&password=password&channel=1&stream=0.sdp?" -y -f image2 -t 0.001 -ss 00:00:3 -s 1280*720 /tmp/screenshot.jpg

    With the same success it was possible to write small videos in mp4, but I thought it was over.
    Photos decided to store blobs in MySQL. The performance decision is so-so, but it will be easier to “drag” the projector, no need to copy both the base and the files, all in the database. And the load on him is essentially nothing.

    As a result, the entry log looks something like this:



    Part 4. Loading numbers from the SQL database on the site to the controller


    If you read carefully, you probably noticed that the USB port of the router worked in the Serial-to-USB converter mode for registering entries, and to work with the database of numbers inside the controller, you had to “push” it through USBIP to your home computer and through Windows program changes. This is not very convenient, you had to do unbind / bind and even run a usbip console on your home computer. Well, it could only be done from home (or, again, RDP / VPN and so on and so forth), and certainly not from a mobile phone. It was doubled that the base of numbers had to be maintained in mdb-format (the program for the controller can upload data in Access) and in the web version.

    The fluent googlezh of the Doorhan GSM work protocol did not give anything. I do not exclude that this is some kind of Chinese devaysina under the brand of Doorhan, however. Therefore, I armed myself with a monitor (sniffer) for the COM port and took several dumps when working from the original application.



    Got something like:
    Command to clean up memory aa 02 09 00 00 03 e8 01 00 00 00 00 ee
    The answer is that everything went well aa 20 00 ee
    team to record one number +79999999999
    aa 03 10 00 01 2b 37 39 39 39 39 39 39 39 39 39 39 00 00 ee

    What made the following conclusions:
    the beginning of sending AA, sending it an end
    response, the team adopted 20 00
    team at the beginning of the record number 03. Then There is a number of numbers in the package. It can be from 1 to 5, that is, for one parcel you can send several numbers in a row at once, ending the parcel with the EE command, and receive one confirmation per block.

    After the command to start recording, there are 2 bytes (the second one is exact, the first one may be used with the number of numbers more than 256 but did not check) indicating the sequence number of the entry in the cell. That is, if you write to empty memory, then first it is 1, then 2, and so on. Then comes 14 byte phone numbers. Since our numbers "enter" into 12 bytes (+79999999999), the last 2 bytes are occupied by zeros. Probably for all international formats such as +10. This is not accurate, I didn’t understand much, because this data was enough.

    The parcel ends with a byte EE.

    With the sequence number of the cell is not quite clear situation. Suppose there are 10 numbers written to the controller, they did not clear the memory. If you send the “write number to cell 5” command, the number in this cell after the control reading will not change, but 11 numbers will be written in the controller, and the 11th will be empty. And if you give the command "write the number in the cell 11", then it will be written into it. This is probably due to the ADD and REPLACE commands (add and edit), which can be sent via SMS. But since the original application does only complete erasure and subsequent rewriting of the list, it is impossible to test the hypothesis. Therefore, I also made my own variant by sending the erase command and sequential recording by one number (for simplicity).

    So, we come to writing commands to the controller via the serial port to manage the list of subscribers. But the port in the router, and the database with users on an external server. Of course, you can transfer it to the router (you get a complete solution out of the box), but I was too lazy. Went the other way - prokinul / dev / ttyUSB0 via tcp using the ser2net package, which is in the openwrt distribution.

    Config /etc/ser2net.conf is simple for indecency

    3333:raw:0:/dev/ttyUSB0:9600,remctl

    After starting ser2net, you can connect to the telnet router on port 3333 and check the result.

    I want to make a reservation: after restarting the router, cat / dev / ttyUSB0 suddenly did not work. That is, of course, it worked, but the garbage was writing to the console. I remembered that during the experiments on the router I ran minicom, which probably did initialize the port. Just setting the mode to 9600 8n1 did not give any results, so I looked at stty with the help of stty which port settings are in the “working” state and entered initialization into rc.local

    stty -F /dev/ttyUSB0 9600 ignbrk -brkint -icrnl -imaxbel -opost -onlcr -isig -icanon -iexten -echo -echoe -echok -echoctl -echoke

    For certain something superfluous, readers will correct probably. Well, if you specify the port settings in ser2net.conf, then you can not put the stty package on the router.

    As a result of these manipulations on the server with the WEB-interface, the controller console became available to us. Therefore, a little rewrite the call processing code. Wrote in PHP. It’s a shame to show all the code (I’m not a programmer after all, but I used inserts from the textbook), so the point is:

     $re = '/CLIP: ".(7\d{10})"/m'; //регэксп на входящий звонокwhile (1) {
       $f=@fsockopen('tcp://10.16.19.19',3333, $errno, $errstr); //подключимся к роутеруwhile ($f && $str=fread($f, 100)) {
         $test=preg_match($re, $str, $matches);
         if ($test)  process_call($matches[1]); //пришел звонок, запишем в базу и сделаем фото//проверим нужно ли записать телефоны из базы в контроллер и сделаем это, если нужно, используя дескриптор $f
         sync_phones($f); 
       }
       if ($f) fclose($f); //что-то пошло не так
       sleep(5); //подождем 5 сек и сделаем реконнект
     }
    

    process_call everyone thinks he realizes how he likes, from writing information to a log file, to creating a photo / video entry and sending them via Telegram-bot to the spouse’s phone, as well as commands to the coffee maker or to warm up the borscht.

    I’ll dwell on sync_phones in more detail, because the very “non-public” algorithm of the Doorhan GSM controller is implemented there. And yes, I used mysql instead of pdo or mysqli.

    functionsync_phones($f){
      /*
     В таблице config хранится переменная update. Если в веб-интерфейсе сделать val=1, то должен запуститься процесс обновления номеров в контроллере. Можно сделать семафор через файл,  но раз я все равно использую mysql, то решил сделать так
     */ 
      $result=mysql_query("SELECT * FROM config WHERE name='update' AND val=1");
      if (mysql_num_rows($result)==0) return; 
      $init =  pack('H*','aa1100ee'); //какой-то пакет инициализации при подключении программы к контроллеру
      $clear = pack('H*','aa0209000003e80100000000ee'); //команда на стирание данных (выдрано с дампа СОМ-порта)
      $logfile=fopen("/tmp/border.log","a");
      fwrite($logfile,"Update started at ".date('Y-m-d H:i:s')."\n");
      fwrite($f,$init);
      sleep(1);
      $ans=fread($f, 40);
      fwrite($logfile,"Send init. Answer ".bin2hex ( $ans )."\n");
      fwrite($f,$clear);
      sleep(1);
      $ans=fread($f, 40);
      fwrite($logfile,"Send clear. Answer ".bin2hex ( $ans )."\n");
      $result=mysql_query("SELECT * FROM phones ORDER BY pid");
      //тут все ясно, select всех номеров из базы пользователей, чтобы записать их в контроллер
      $n=1;
      while($row=mysql_fetch_array($result)) {
        $start = 'aa0310';
        $pos   = sprintf("%04x",$n);
        $phone = bin2hex('+'.$row['phone']).'0000';
        $end   = 'ee';
        //собираем "посылку"
        $send=$start.$pos.$phone.$end;
        $bin=pack('H*',$send);
        fwrite($f,$bin);
        $ans=fread($f, 40);
        fwrite($logfile,"Write {$n} phone {$row['phone']}. Answer ".bin2hex ( $ans )."\n");
        $n++;
      }
      fwrite($logfile,"End update\n");
      fclose($logfile);
      //запишем в наш "семафор" время, когда обновление завершено, полезная информация. И сам флажок, что обновление не требуется
      mysql_query("UPDATE config SET val=0,result='".bin2hex ( $ans )."',updated=NOW() WHERE name='update'");
    }
    ?>

    Part 5. Conclusion


    As a result, I received (wrote) the WEB-interface for the barrier, where I can go through the mobile browser, add / delete / change the numbers of residents of our house, make notes, with reference to the apartment, full name, phone number, car number. There are photos of cars, log entries through the barrier with a photo. In the future, according to the logs, I’ll see who creates the greatest load on the barrier - he will pay for repairs :)

    Well, I received a bonus WIFI point in the parking lot near the house.

    Issue price - 0 rubles and the output for the computer.

    Also popular now: