MySVC
an open source UNIX framework for shell script based web services provider
»Home
»Tools
»Man Page
»User Guide
»ChangeLog
»Installation
»Source Code
»Downloads
»FAQ
»Support
»License

»My Apps

wildfire.cc

// $Id$

//  myspl - My Service Protocol Library - Version 1.0 (www.mysvc.it)
//  Copyright (C) 2009 Davide Cucciniello <davide6169@gmail.com>
//
//  This program is free software: you can redistribute it and/or modify
//  it under the terms of the GNU General Public License as published by
//  the Free Software Foundation, either version 3 of the License, or
//  (at your option) any later version.
//
//  This program is distributed in the hope that it will be useful,
//  but WITHOUT ANY WARRANTY; without even the implied warranty of
//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
//  GNU General Public License for more details.
//
//  You should have received a copy of the GNU General Public License
//  along with this program.  If not, see <http://www.gnu.org/licenses/>.

/* **********************************************************************
 *
 *  ***   **        *** **  **  ****
 *   **  **        *  *  *  ** **  *
 *   *** **  **  * ***   *  *  *
 *   * ** *   * **   **   * *  *
 *   * *  *   * *  *  *   **   **
 *  ***  ***   **  ***     *    ****
 *             *
 *            *
 *
 *  My Service
 *
 * ***********************************************************************
 *
 *  ***   **        *** ****  ***
 *   **  **        *  *  *  *  *
 *   *** **  **  * ***   *  *  *
 *   * ** *   * **   **  ***   *
 *   * *  *   * *  *  *  *     *  *
 *  ***  ***   **  ***  ***   *****
 *             *
 *            *
 *
 *  My Service Protocol Library Example Client (Wildfire VMS Client)
 *
 *  File: wildfire.cc
 *
 *  Description:
 *    Wildfire VMS Client as usage example for MySPL library
 *    (realized for provisioning of "Memory" service
 *     in BLU mobile telephone operator)
 *
 * ***********************************************************************
 *
 *  History:
 *    1.0               first version
 *
 * *********************************************************************** */

#include "upsp.hh"

// Default values

#define WF_IPADDRESS "10.133.52.66"
#define WF_PORT      16725
#define WF_VERSION   "4"
#define WF_USERNAME  "blu1db01"
#define WF_PASSWORD  "10.133.52.66"

// Wildfire VRU

#define WF_VRU1      "blu1v01"
#define WF_VRU2      "blu1v02"
#define WF_VRU3      "blu1v03"

// Error codes

#define WF_INTERNAL_ERROR   1
#define WF_CONNECTION_ERROR 2
#define WF_LOGIN_ERROR      3
#define WF_COMMAND_ERROR    4
#define WF_LOGOUT_ERROR     5

// Commands

#define WF_TEST    1
#define WF_CREATE  2
#define WF_QUERY   3
#define WF_FIND    4
#define WF_SET     5
#define WF_REMOVE  6

using namespace std;

//
// Main
//

int main(int argc,char* argv[])
{
  // Default values

  string ipaddress = WF_IPADDRESS;
  int port = WF_PORT;
  string wf_version = WF_VERSION;
  string username = WF_USERNAME;
  string password = WF_PASSWORD;

  int command = WF_TEST;

  string msisdn;
  string imsi;
  string firstname;
  string lastname;
  string hostname;
  string service;

  int fieldindex = -1;
  string fieldvalue;

  // Trace UPSP commands

  bool upsp_trace = false;
  bool upsp_log = false;

  // Parsing command line options

  int option;

  while((option = getopt(argc,argv,":hlta:P:v:u:p:cqfdrsx:y:m:i:n:S:F:L:123")) != EOF)
  {
    switch(option)
    {
      case 'h':
        cerr << "usage: wildfire [-l]" << endl;
        cerr << "                [-t]" << endl;
        cerr << "                [-a <ipaddress>]" << endl;
        cerr << "                [-P <port>]" << endl;
        cerr << "                [-v <version>]" << endl;
        cerr << "                [-u <username>]" << endl;
        cerr << "                [-p <password>]" << endl;
        cerr << "                [-c|-q|-f|-s|-d|-r]" << endl;
        cerr << "                [-1|-2|-3]" << endl;
        cerr << "                [-x <fieldindex>]" << endl;
        cerr << "                [-y <fieldvalue>]" << endl;
        cerr << "                [-m <msisdn>]" << endl;
        cerr << "                [-i <imsi>]" << endl;
        cerr << "                [-n <hostname>]" << endl;
        cerr << "                [-S <service>]" << endl;
        cerr << "                [-F <firstname>]" << endl;
        cerr << "                [-L <lastname>]" << endl;
        cerr << endl;
        cerr << "  -c => create" << endl;
        cerr << "  -q => query" << endl;
        cerr << "  -f => find" << endl;
        cerr << "  -s => set" << endl;
        cerr << "  -d => delete" << endl;
        cerr << "  -r => remove" << endl;

        return WF_INTERNAL_ERROR;
        break;
      case 'l':
        upsp_log = true;
        break;
      case 't':
        upsp_trace = true;
        break;
      case 'a':
        ipaddress = optarg;
        break;
      case 'P':
        port = atoi(optarg);
        break;
      case 'v':
        wf_version = optarg;
        break;
      case 'u':
        username = optarg;
        break;
      case 'p':
        password = optarg;
        break;
      case 'c':
        command = WF_CREATE;
        break;
      case 'q':
        command = WF_QUERY;
        break;
      case 'f':
        command = WF_FIND;
        break;
      case 's':
        command = WF_SET;
        break;
      case 'd':
        command = WF_SET;
        fieldindex = 17;
        fieldvalue = "true";
        break;
      case 'r':
        command = WF_REMOVE;
        break;
      case 'x':
        fieldindex = atoi(optarg);
        break;
      case 'y':
        fieldvalue = optarg;
        break;
      case '1':
        hostname = WF_VRU1;
        break;
      case '2':
        hostname = WF_VRU2;
        break;
      case '3':
        hostname = WF_VRU3;
        break;
      case 'm':
        msisdn = optarg;
        break;
      case 'i':
        imsi = optarg;
        break;
      case 'n':
        hostname = optarg;
        break;
      case 'S':
        service = optarg;
        break;
      case 'F':
        firstname = optarg;
        break;
      case 'L':
        lastname = optarg;
        break;
    }
  }

  try
  {
    SocketClient wildfire(ipaddress,port);

    // Connection to wildfire ...

    if(upsp_log)
      cerr << "Connecting to Wildfire ..." << endl;

    wildfire.connect();

    UPSPHeader               header;

    UPSPVersion              version;
    UPSPUniversalNAck        universal_nack_body;
    UPSPLoginReq             login_req;
    UPSPLoginNAckBody        login_nack_body;
    UPSPLoopReq              loop_req;
    UPSPLoopAckBody          loop_ack_body;
    UPSPLoopNAckBody         loop_nack_body;
    UPSPCreateReq            create_req;
    UPSPCreateAckBody        create_ack_body;
    UPSPCreateNAckBody       create_nack_body;
    UPSPGetAllReq            get_all_req;
    UPSPGetAllAckBody        get_all_ack_body;
    UPSPGetAllNAckBody       get_all_nack_body;
    UPSPFindReq              find_req;
    UPSPFindAckBody          find_ack_body;
    UPSPFindNAckBody         find_nack_body;
    UPSPSetReq               set_req;
    UPSPSetNAckBody          set_nack_body;
    UPSPRemoveSubscReq       remove_subsc_req;
    UPSPRemoveSubscAck       remove_subsc_ack;
    UPSPRemoveSubscNAckBody  remove_subsc_nack_body;
    UPSPLogoutReq            logout_req;
    UPSPLogoutNAckBody       logout_nack_body;

    int msg_type;

    // Login ...

    if(upsp_log)
      cerr << "Sending version ..." << endl;

    version[4] = wf_version;

    if(upsp_log)
    {
      if(upsp_trace)
        cerr << version << endl;
      cerr << "  <version> = <"
           << ((Int4Field&) version[4]).value()
           << ">" << endl;
    }

    wildfire << version;

    login_req[4] = username;
    login_req[5] = password;

    if(upsp_log)
    {
      cerr << "Sending login_req ..." << endl;
      if(upsp_trace)
        cerr << login_req;
      cerr << "  <username> = <" << username << ">" << endl;
      cerr << "  <password> = <" << password << ">" << endl;
    }

    wildfire << login_req;

    if(upsp_log)
      cerr << "Reading ..." << endl;

    wildfire >> header;

    if(upsp_log)
    {
      if(upsp_trace)
        cerr << header << endl;
    }

    msg_type = (Int2Field&) header[1];

    switch(msg_type)
    {
      case UPSP_LOGIN_ACK:
      {
        if(upsp_log)
          cerr << "Received login_ack ..." << endl;

        break;
      }
      case UPSP_LOGIN_NACK:
      {
        if(upsp_log)
        {
          cerr << "Received login_nack ..." << endl;
          cerr << "Reading login_nack body ..." << endl;
        }

        wildfire >> login_nack_body;

        if(upsp_log)
        {
          if(upsp_trace)
            cerr << login_nack_body << endl;
          cerr << "  <error_code> = <"
               << ((Int4Field&) login_nack_body[0]).value()
               << ">" << endl;
          cerr << "  <error_msg> = <"
               << ((StringField&) login_nack_body[1]).value()
               << ">" << endl;
        }

        break;
      }
      case UPSP_UNIVERSAL_NACK:
      {
        if(upsp_log)
        {
          cerr << "Received universal_nack ..." << endl;
          cerr << "Reading universal_nack body ..." << endl;
        }

        wildfire >> universal_nack_body;

        if(upsp_log)
        {
          if(upsp_trace)
            cerr << universal_nack_body << endl;
          cerr << "  <error_code> = <"
               << ((Int4Field&) universal_nack_body[0]).value()
               << ">" << endl;
          cerr << "  <error_msg> = <"
               << ((StringField&) universal_nack_body[1]).value()
               << ">" << endl;
        }

        break;
      }
      default:
        if(upsp_log)
          cerr << "Unknown message type ..." << endl;
        break;
    }

    if(msg_type != UPSP_LOGIN_ACK)
    {
      if(upsp_log)
        cerr << "Closing connection ... " << endl;
      wildfire.close();

      return WF_LOGIN_ERROR;
    }

    // Command execute ...

    switch(command)
    {
      // --------------------------
      case WF_TEST:
      {
        if(upsp_log)
        {
          cerr << "Sending loop_req ..." << endl;
          if(upsp_trace)
            cerr << loop_req;
        }

        wildfire << loop_req;

        if(upsp_log)
          cerr << "Reading ..." << endl;

        wildfire >> header;

        msg_type = (Int2Field&) header[1];

        if(upsp_trace)
          cerr << header << endl;

        switch(msg_type)
        {
          case UPSP_LOOP_ACK:
          {
            if(upsp_log)
            {
              cerr << "Received loop_ack ..." << endl;
              cerr << "Reading loop_ack body ..." << endl;
            }

            wildfire >> loop_ack_body;

            if(upsp_log)
            {
              if(upsp_trace)
                cerr << loop_ack_body << endl;
              cerr << "  <count> = <"
                   << ((Int4Field&) loop_ack_body[0]).value()
                   << ">" << endl;
            }

            break;
          }
          case UPSP_LOOP_NACK:
          {
            if(upsp_log)
            {
              cerr << "Received loop_nack ..." << endl;
              cerr << "Reading loop_nack body ..." << endl;
            }

            wildfire >> loop_nack_body;

            if(upsp_log)
            {
              if(upsp_trace)
                cerr << loop_nack_body << endl;
              cerr << "  <error_code> = <"
                   << ((Int4Field&) loop_nack_body[0]).value()
                   << ">" << endl;
              cerr << "  <error_msg> = <"
                   << ((StringField&) loop_nack_body[1]).value()
                   << ">" << endl;
            }

            break;
          }
          case UPSP_UNIVERSAL_NACK:
          {
            if(upsp_log)
            {
              cerr << "Received universal_nack ..." << endl;
              cerr << "Reading universal_nack body ..." << endl;
            }

            wildfire >> universal_nack_body;

            if(upsp_log)
            {
              if(upsp_trace)
                cerr << universal_nack_body << endl;
              cerr << "  <error_code> = <"
                   << ((Int4Field&) universal_nack_body[0]).value()
                   << ">" << endl;
              cerr << "  <error_msg> = <"
                   << ((StringField&) universal_nack_body[1]).value()
                   << ">" << endl;
            }

            break;
          }
          default:
            if(upsp_log)
              cerr << "Unknown message type ..." << endl;
            break;
        }

        if(msg_type != UPSP_LOOP_ACK)
        {
          if(upsp_log)
            cerr << "Closing connection ... " << endl;

          wildfire.close();

          return WF_COMMAND_ERROR;
        }

        break;
      }
      // --------------------------
      // --------------------------
      case WF_QUERY:
      {
        get_all_req[4] = msisdn;

        if(upsp_log)
        {
          cerr << "Sending get_all_req ..." << endl;
          if(upsp_trace)
            cerr << get_all_req;
          cerr << "  <phone_number> = <" << msisdn << ">" << endl;
        }

        wildfire << get_all_req;

        if(upsp_log)
          cerr << "Reading ..." << endl;

        wildfire >> header;

        msg_type = (Int2Field&) header[1];

        if(upsp_log)
        {
          if(upsp_trace)
            cerr << header << endl;
        }

        switch(msg_type)
        {
          case UPSP_GET_ALL_ACK:
          {
            if(upsp_log)
            {
              cerr << "Received get_all_ack ..." << endl;
              cerr << "Reading get_all_ack body ..." << endl;
            }

            wildfire >> get_all_ack_body;

            cout << ((StringField&) get_all_ack_body[1]).value()
                 << ","
                 << ((StringField&) get_all_ack_body[2]).value()
                 << endl;

            if(upsp_log)
            {
              if(upsp_trace)
                cerr << get_all_ack_body << endl;
              cerr << "  <first_name> = <"
                   << ((StringField&) get_all_ack_body[1]).value()
                   << ">" << endl;
              cerr << "  <last_name> = <"
                   << ((StringField&) get_all_ack_body[2]).value()
                   << ">" << endl;
              cerr << "  <phone_number> = <"
                   << ((StringField&) get_all_ack_body[5]).value()
                   << ">" << endl;
              cerr << "  <fax_number> = <"
                   << ((StringField&) get_all_ack_body[7]).value()
                   << ">" << endl;
              cerr << "  <disabled> = <"
                   << ((BoolField&) get_all_ack_body[9]).value()
                   << ">" << endl;
              cerr << "  <host_name> = <"
                   << ((StringField&) get_all_ack_body[10]).value()
                   << ">" << endl;
              cerr << "  <intl_calls> = <"
                   << ((BoolField&) get_all_ack_body[13]).value()
                   << ">" << endl;
              cerr << "  <num_services> = <"
                   << ((Int4Field&) get_all_ack_body[22]).value()
                   << ">" << endl;
            }

            break;
          }
          case UPSP_GET_ALL_NACK:
          {
            if(upsp_log)
            {
              cerr << "Received get_all_nack ..." << endl;
              cerr << "Reading get_all_nack body ..." << endl;
            }

            wildfire >> get_all_nack_body;

            if(upsp_log)
            {
              if(upsp_trace)
                cerr << get_all_nack_body << endl;
              cerr << "  <error_code> = <"
                   << ((Int4Field&) get_all_nack_body[0]).value()
                   << ">" << endl;
              cerr << "  <error_msg> = <"
                   << ((StringField&) get_all_nack_body[1]).value()
                   << ">" << endl;
            }

            break;
          }
          case UPSP_UNIVERSAL_NACK:
          {
            if(upsp_log)
            {
              cerr << "Received universal_nack ..." << endl;
              cerr << "Reading universal_nack body ..." << endl;
            }

            wildfire >> universal_nack_body;

            if(upsp_log)
            {
              if(upsp_trace)
                cerr << universal_nack_body << endl;
              cerr << "  <error_code> = <"
                   << ((Int4Field&) universal_nack_body[0]).value()
                   << ">" << endl;
              cerr << "  <error_msg> = <"
                   << ((StringField&) universal_nack_body[1]).value()
                   << ">" << endl;
            }

            break;
          }
          default:
            if(upsp_log)
              cerr << "Unknown message type ..." << endl;
            break;
        }

        if(msg_type != UPSP_GET_ALL_ACK)
        {
          if(upsp_log)
            cerr << "Closing connection ... " << endl;

          wildfire.close();

          return WF_COMMAND_ERROR;
        }

        break;
      }
      // --------------------------
      // --------------------------
      case WF_CREATE:
      {
        create_req[5] = firstname;
        create_req[6] = lastname;
        create_req[9] = msisdn;
        create_req[14] = "false";

        if(!hostname.empty())
          create_req[15] = hostname;
        else if(!imsi.empty())
        {
          string hlr_id = imsi.substr(5,2);

          // 2229811... => 11
          // 2229821... => 21
          // ...

          if((hlr_id == "11") || (hlr_id == "12"))  // VRU1
            create_req[15] = WF_VRU1;
          else if((hlr_id == "21") || (hlr_id == "22"))  // VRU2
            create_req[15] = WF_VRU2;
          else if((hlr_id == "31") || (hlr_id == "32"))  // VRU3
            create_req[15] = WF_VRU3;
          else
          {
            if(upsp_log)
            {
              cerr << "Undefined hlr for imsi <" << imsi << ">" << endl;
              cerr << "Closing connection ... " << endl;
            }

            wildfire.close();

            return WF_INTERNAL_ERROR;
          }
        }
        else
        {
          if(upsp_log)
          {
            cerr << "Undefined hostname" << endl;
            cerr << "Closing connection ... " << endl;
          }

          wildfire.close();

          return WF_INTERNAL_ERROR;
        }

        create_req[18] = "true";
        create_req[25] = "Basic";

        if(upsp_log)
        {
          cerr << "Sending create_req ..." << endl;
          if(upsp_trace)
            cerr << create_req;
        }

        wildfire << create_req;

        if(upsp_log)
          cerr << "Reading ..." << endl;

        wildfire >> header;

        msg_type = (Int2Field&) header[1];

        if(upsp_trace)
          cerr << header << endl;

        switch(msg_type)
        {
          case UPSP_CREATE_ACK:
          {
            if(upsp_log)
            {
              cerr << "Received create_ack ..." << endl;
              cerr << "Reading create_ack body ..." << endl;
            }

            wildfire >> create_ack_body;

            if(upsp_log)
            {
              if(upsp_trace)
                cerr << create_ack_body << endl;
              cerr << "  <forward_on_busy> = <"
                   << ((StringField&) create_ack_body[0]).value()
                   << ">" << endl;
              cerr << "  <host_name> = <"
                   << ((StringField&) create_ack_body[1]).value()
                   << ">" << endl;
              cerr << "  <curreny_capacity> = <"
                   << ((Int4Field&) create_ack_body[2]).value()
                   << ">" << endl;
            }

            break;
          }
          case UPSP_CREATE_NACK:
          {
            if(upsp_log)
            {
              cerr << "Received create_nack ..." << endl;
              cerr << "Reading create_nack body ..." << endl;
            }

            wildfire >> create_nack_body;

            if(upsp_log)
            {
              if(upsp_trace)
                cerr << create_nack_body << endl;
              cerr << "  <error_code> = <"
                   << ((Int4Field&) create_nack_body[0]).value()
                   << ">" << endl;
              cerr << "  <error_msg> = <"
                   << ((StringField&) create_nack_body[1]).value()
                   << ">" << endl;
            }

            break;
          }
          case UPSP_UNIVERSAL_NACK:
          {
            if(upsp_log)
            {
              cerr << "Received universal_nack ..." << endl;
              cerr << "Reading universal_nack body ..." << endl;
            }

            wildfire >> universal_nack_body;

            if(upsp_log)
            {
              if(upsp_trace)
                cerr << universal_nack_body << endl;
              cerr << "  <error_code> = <"
                   << ((Int4Field&) universal_nack_body[0]).value()
                   << ">" << endl;
              cerr << "  <error_msg> = <"
                   << ((StringField&) universal_nack_body[1]).value()
                   << ">" << endl;
            }

            break;
          }
          default:
            if(upsp_log)
              cerr << "Unknown message type ..." << endl;
            break;
        }

        if(msg_type != UPSP_CREATE_ACK)
        {
          if(upsp_log)
            cerr << "Closing connection ... " << endl;

          wildfire.close();

          return WF_COMMAND_ERROR;
        }

        break;
      }
      // --------------------------
      // --------------------------
      case WF_FIND:
      {
        if(upsp_log)
        {
          cerr << "Sending find_req ..." << endl;
          if(upsp_trace)
            cerr << find_req;
        }

        wildfire << find_req;

        if(upsp_log)
        {
          cerr << "  <first_name> = <" << firstname << ">" << endl;
          cerr << "  <last_name> = <" << lastname << ">" << endl;

          cerr << "Reading ..." << endl;
        }

        wildfire >> header;

        msg_type = (Int2Field&) header[1];

        if(upsp_log)
        {
          if(upsp_trace)
            cerr << header << endl;
        }

        switch(msg_type)
        {
          case UPSP_FIND_ACK:
          {
            if(upsp_log)
            {
              cerr << "Received find_ack ..." << endl;
              cerr << "Reading find_ack body ..." << endl;
            }

            wildfire >> find_ack_body;

            if(upsp_log)
            {
              if(upsp_trace)
                cerr << find_ack_body << endl;
              cerr << "  <num_phone_number> = <"
                   << ((Int4Field&) find_ack_body[0]).value()
                   << ">" << endl;
              cerr << "  <phone_number> = <"
                   << ((StringField&) find_ack_body[1]).value()
                   << ">" << endl;
            }

            break;
          }
          case UPSP_FIND_NACK:
          {
            if(upsp_log)
            {
              cerr << "Received find_nack ..." << endl;
              cerr << "Reading find_nack body ..." << endl;
            }

            wildfire >> find_nack_body;

            if(upsp_log)
            {
              if(upsp_trace)
                cerr << find_nack_body << endl;
              cerr << "  <error_code> = <"
                   << ((Int4Field&) find_nack_body[0]).value()
                   << ">" << endl;
              cerr << "  <error_msg> = <"
                   << ((StringField&) find_nack_body[1]).value()
                   << ">" << endl;
            }

            break;
          }
          case UPSP_UNIVERSAL_NACK:
          {
            if(upsp_log)
            {
              cerr << "Received universal_nack ..." << endl;
              cerr << "Reading universal_nack body ..." << endl;
            }

            wildfire >> universal_nack_body;

            if(upsp_log)
            {
              if(upsp_trace)
                cerr << universal_nack_body << endl;
              cerr << "  <error_code> = <"
                   << ((Int4Field&) universal_nack_body[0]).value()
                   << ">" << endl;
              cerr << "  <error_msg> = <"
                   << ((StringField&) universal_nack_body[1]).value()
                   << ">" << endl;
            }

            break;
          }
          default:
            if(upsp_log)
              cerr << "Unknown message type ..." << endl;
            break;
        }

        if(msg_type != UPSP_FIND_ACK)
        {
          if(upsp_log)
            cerr << "Closing connection ... " << endl;

          wildfire.close();

          return WF_COMMAND_ERROR;
        }

        break;
      }
      // --------------------------
      // --------------------------
      case WF_SET:
      {
        if(fieldindex <2 || fieldindex >31)
        {
          if(upsp_log)
          {
            cerr << "Invalid field index" << endl;
            cerr << "Closing connection ... " << endl;
          }

          wildfire.close();

          return WF_INTERNAL_ERROR;
        }

        set_req[4] = msisdn;
        set_req[fieldindex] = fieldvalue;

        if(upsp_log)
        {
          cerr << "Sending set_req ..." << endl;
          if(upsp_trace)
            cerr << set_req;
        }

        wildfire << set_req;

        if(upsp_log)
        {
          cerr << "  <" << (set_req[fieldindex].name())
               << "> = <" << fieldvalue << ">" << endl;

          cerr << "Reading ..." << endl;
        }

        wildfire >> header;

        msg_type = (Int2Field&) header[1];

        if(upsp_trace)
          cerr << header << endl;

        switch(msg_type)
        {
          case UPSP_SET_ACK:
          {
            if(upsp_log)
            {
              cerr << "Received set_ack ..." << endl;
              if(upsp_trace)
                cerr << header << endl;
            }

            break;
          }
          case UPSP_SET_NACK:
          {
            if(upsp_log)
            {
              cerr << "Received set_nack ..." << endl;
              cerr << "Reading set_nack body ..." << endl;
            }

            wildfire >> set_nack_body;

            if(upsp_log)
            {
              if(upsp_trace)
                cerr << set_nack_body << endl;
              cerr << "  <error_code> = <"
                   << ((Int4Field&) find_nack_body[0]).value()
                   << ">" << endl;
              cerr << "  <error_msg> = <"
                   << ((StringField&) set_nack_body[1]).value()
                   << ">" << endl;
            }

            break;
          }
          case UPSP_UNIVERSAL_NACK:
          {
            if(upsp_log)
            {
              cerr << "Received universal_nack ..." << endl;
              cerr << "Reading universal_nack body ..." << endl;
            }

            wildfire >> universal_nack_body;

            if(upsp_log)
            {
              if(upsp_trace)
                cerr << universal_nack_body << endl;
              cerr << "  <error_code> = <"
                   << ((Int4Field&) universal_nack_body[0]).value()
                   << ">" << endl;
              cerr << "  <error_msg> = <"
                   << ((StringField&) universal_nack_body[1]).value()
                   << ">" << endl;
            }

            break;
          }
          default:
            if(upsp_log)
              cerr << "Unknown message type ..." << endl;
            break;
        }

        if(msg_type != UPSP_SET_ACK)
        {
          if(upsp_log)
            cerr << "Closing connection ... " << endl;

          wildfire.close();

          return WF_COMMAND_ERROR;
        }

        break;
      }
      // --------------------------
      // --------------------------
      case WF_REMOVE:
      {
        remove_subsc_req[4] = msisdn;
        remove_subsc_req[5] = service;

        if(upsp_log)
        {
          cerr << "Sending remove_subsc_req ..." << endl;
          if(upsp_trace)
            cerr << remove_subsc_req;
        }

        wildfire << remove_subsc_req;

        if(upsp_log)
          cerr << "Reading ..." << endl;

        wildfire >> header;

        msg_type = (Int2Field&) header[1];

        if(upsp_trace)
          cerr << header << endl;

        switch(msg_type)
        {
          case UPSP_REMOVE_SUBSC_ACK:
          {
            if(upsp_log)
            {
              cerr << "Received remove_subsc_ack ..." << endl;
              cerr << "Reading remove_subsc_ack ..." << endl;
            }

            wildfire >> remove_subsc_ack;

            if(upsp_log)
            {
              if(upsp_trace)
                cerr << remove_subsc_ack << endl;
            }

            break;
          }
          case UPSP_REMOVE_SUBSC_NACK:
          {
            if(upsp_log)
            {
              cerr << "Received remove_subsc_nack ..." << endl;
              cerr << "Reading remove_subsc_nack body ..." << endl;
            }

            wildfire >> remove_subsc_nack_body;

            if(upsp_log)
            {
              if(upsp_trace)
                cerr << remove_subsc_nack_body << endl;
              cerr << "  <error_code> = <"
                   << ((Int4Field&) remove_subsc_nack_body[0]).value()
                   << ">" << endl;
              cerr << "  <error_msg> = <"
                   << ((StringField&) remove_subsc_nack_body[1]).value()
                   << ">" << endl;
            }

            break;
          }
          case UPSP_UNIVERSAL_NACK:
          {
            if(upsp_log)
            {
              cerr << "Received universal_nack ..." << endl;
              cerr << "Reading universal_nack body ..." << endl;
            }

            wildfire >> universal_nack_body;

            if(upsp_log)
            {
              if(upsp_trace)
                cerr << universal_nack_body << endl;
              cerr << "  <error_code> = <"
                   << ((Int4Field&) universal_nack_body[0]).value()
                   << ">" << endl;
              cerr << "  <error_msg> = <"
                   << ((StringField&) universal_nack_body[1]).value()
                   << ">" << endl;
            }

            break;
          }
          default:
            if(upsp_log)
              cerr << "Unknown message type ..." << endl;
            break;
        }

        if(msg_type != UPSP_REMOVE_SUBSC_ACK)
        {
          if(upsp_log)
            cerr << "Closing connection ... " << endl;

          wildfire.close();

          return WF_COMMAND_ERROR;
        }

        break;
      }
      // --------------------------
    }

    // Logout ...

    if(upsp_log)
    {
      cerr << "Sending logout_req ..." << endl;
      if(upsp_trace)
        cerr << logout_req;
    }

    wildfire << logout_req;

    if(upsp_log)
      cerr << "Reading ..." << endl;

    wildfire >> header;

    msg_type = (Int2Field&) header[1];

    if(upsp_log)
    {
      if(upsp_trace)
        cerr << header << endl;
    }

    switch(msg_type)
    {
      case UPSP_LOGOUT_ACK:
      {
        if(upsp_log)
          cerr << "Received logout_ack ..." << endl;

        break;
      }
      case UPSP_LOGOUT_NACK:
      {
        if(upsp_log)
        {
          cerr << "Received logout_nack ..." << endl;
          cerr << "Reading logout_nack body ..." << endl;
        }

        wildfire >> logout_nack_body;

        if(upsp_log)
        {
          if(upsp_trace)
            cerr << logout_nack_body << endl;
          cerr << "  <error_code> = <"
               << ((Int4Field&) logout_nack_body[0]).value()
               << ">" << endl;
          cerr << "  <error_msg> = <"
               << ((StringField&) logout_nack_body[1]).value()
               << ">" << endl;
        }

        break;
      }
      case UPSP_UNIVERSAL_NACK:
      {
        if(upsp_log)
        {
          cerr << "Received universal_nack ..." << endl;
          cerr << "Reading universal_nack body ..." << endl;
        }

        wildfire >> universal_nack_body;

        if(upsp_log)
        {
          if(upsp_trace)
            cerr << universal_nack_body << endl;
          cerr << "  <error_code> = <"
               << ((Int4Field&) universal_nack_body[0]).value()
               << ">" << endl;
          cerr << "  <error_msg> = <"
               << ((StringField&) universal_nack_body[1]).value()
               << ">" << endl;
        }

        break;
      }
      default:
        if(upsp_log)
          cerr << "Unknown message type ..." << endl;
        break;
    }

    if(upsp_log)
      cerr << "Closing connection ... " << endl;

    wildfire.close();

    if(upsp_log)
      cerr << "Done" << endl;
  }
  catch(SocketException e)
  {
    cerr << e << endl;

    return WF_CONNECTION_ERROR;
  }
  catch(Exception e)
  {
    cerr << e << endl;

    return WF_INTERNAL_ERROR;
  }
  catch(exception e)
  {
    cerr << "System exception" << endl;

    return WF_INTERNAL_ERROR;
  }
  catch(...)
  {
    cerr << "Unknown exception" << endl;

    return WF_INTERNAL_ERROR;
  }

  return 0;
}

/* end of file */