MockNamedValue MockActualFunctionCall::returnValue()
{
	checkExpectations();
	if (_fulfilledExpectation)
		return _fulfilledExpectation->returnValue();
	return MockNamedValue("no return value");
}
bool NavKeyedDataHandler::
handleGetKeyedData( LangTypes::language_t language,
                    NavRequestPacket* pack, 
                    NavReplyPacket* reply ) 
try {
   if ( !checkExpectations( pack->getParamBlock(), reply ) ) {
      return false;
   }

   MC2String key;
   uint32 crc;
   bool sentCRC;

   getParameters( pack->getParamBlock(), key, crc, sentCRC );

   logParameters( key, language, crc, sentCRC);

   vector<byte> data;
   getDataForKey( key, language, data );

   uint32 newCrc = MC2CRC32::crc32( &data.front(), data.size() );

   if ( !sentCRC || crc != newCrc ) {
      NParamBlock& rparams = reply->getParamBlock();

      rparams.addParam( NParam( 6101, newCrc ) );
      addDataAsParams( rparams, data );
   }
   return true;
} catch ( const MC2Exception& e ) {
   mc2log << warn << "handleGetKeyedData: " << e.what() << endl;
   reply->setStatusCode( NavReplyPacket::NAV_STATUS_NOT_OK );
   return false;
}
Beispiel #3
0
MockNamedValue MockCheckedActualCall::returnValue()
{
    checkExpectations();
    if (fulfilledExpectation_)
        return fulfilledExpectation_->returnValue();
    return MockNamedValue("no return value");
}
bool
NavVerifyThirdPartyTransactionHandler::handleVerifyThirdPartyTransaction( 
   NavRequestData& rd )
{
   if ( !checkExpectations( rd.params, rd.reply ) ) {
      return false;
   }

   bool ok = true;

   // Start parameter printing
   mc2log << info << "handleVerifyThirdPartyTransaction:";

   stringstream inputData;
   // Verification String
   MC2String verifyString;
   if ( getParam( 6400, verifyString, rd.params ) ) {
      inputData << "  " << verifyString;
   }
   // Error Data Selection String
   MC2String selectionString;
   if ( getParam( 6401, selectionString, rd.params ) ) {
      inputData << "  " << selectionString;
   }

   mc2log << inputData.str();

   // End parameter printing
   mc2log << endl;

   // Split selectionString on ;
   vector<MC2String> selectionArray = STLStringUtility::explode( 
      ";", selectionString );
   
   if ( selectionArray.size() == 2 ) {
      if ( selectionArray[ 0 ] == "iPhoneAppStore" ) {
         // verifyString to AppStoreHandler
         bool verified = m_thread->getAppStore().verifyReceipt( verifyString );
         if ( ! verified ) {
            rd.reply->setStatusCode( NavReplyPacket::NAV_STATUS_NOT_OK );
         }
         mc2log << info << "handleVerifyThirdPartyTransaction: Verify "
                << (verified ? "Successful" : "Failed" ) << endl;
      } else {
         mc2log << "handleVerifyThirdPartyTransaction: unknown error data "
                << "type : " << MC2CITE( selectionArray[ 0 ] )  << endl;
         rd.reply->setStatusCode( NavReplyPacket::NAV_STATUS_NOT_OK );
      }
   } else {
      mc2log << "handleVerifyThirdPartyTransaction: bad format on "
             << "Selection String: " << MC2CITE( selectionString )  << endl;
      rd.reply->setStatusCode( NavReplyPacket::NAV_STATUS_NOT_OK );
   }

   return ok;
}
bool
NavMapHandler::handleMap( UserItem* userItem, 
                          NavRequestPacket* req, 
                          NavReplyPacket* reply )
{
   if ( !checkExpectations( req->getParamBlock(), reply ) ) {
      return false;
   }

   bool ok = true;

   // The params
   const NParamBlock& params = req->getParamBlock();
   NParamBlock& rparams = reply->getParamBlock();
   // The user
   UserUser* user = userItem->getUser();
   uint32 startTime = TimeUtility::getCurrentTime();


   // Start parameter printing
   mc2log << info << "handleMap:";

   StringTable::languageCode language = user->getLanguage();
   if ( params.getParam( 6 ) ) {
      language = NavUtil::mc2LanguageCode( 
         params.getParam( 6 )->getUint16() );
      mc2log << " Lang " << StringTable::getString( 
         StringTable::getLanguageAsStringCode( language ), 
         StringTable::ENGLISH );
   }
   
   // MapBoundingbox
   MC2BoundingBox mapBbox;
   if ( params.getParam( 1600 ) ) {
      MC2Coordinate topLeft( 
         Nav2Coordinate( params.getParam( 1600 )->getInt32Array( 0 ),
                         params.getParam( 1600 )->getInt32Array( 1 ) ) );
      MC2Coordinate bottomRight( 
         Nav2Coordinate( params.getParam( 1600 )->getInt32Array( 2 ),
                         params.getParam( 1600 )->getInt32Array( 3 ) ) );
      mapBbox.setMaxLat( topLeft.lat );
      mapBbox.setMinLon( topLeft.lon );
      mapBbox.setMinLat( bottomRight.lat );
      mapBbox.setMaxLon( bottomRight.lon );
      mc2log << " MapBoundingbox " << mapBbox;
   }

   MC2Coordinate mapPos;
   if ( params.getParam( 1601 ) ) {
      mapPos = MC2Coordinate( 
         Nav2Coordinate( params.getParam( 1601 )->getInt32Array( 0 ),
                         params.getParam( 1601 )->getInt32Array( 1 ) ) );
      mc2log << " MapPosition " << mapPos;
   }

   float32 speed = 666.999;
   if ( params.getParam( 1602 ) ) {
      if ( params.getParam( 1602 )->getUint16() < MAX_INT16 ) {
         speed = float32(params.getParam( 1602 )->getUint16())/32;
         mc2log << " speed " << speed;
      } else {
         mc2log << " speed N/A";
      }
   }

   uint16 heading = MAX_UINT16;
   if ( params.getParam( 1603 ) ) {
      if ( params.getParam( 1603 )->getUint16() < 256 ) {
         heading = uint16( rint( params.getParam( 1603 )->getUint16() * 
                                 360.0 / 256.0 ) );
         mc2log << " heading " << heading << "°";
      } else {
         mc2log << " heading N/A";
      }
   }

   uint32 mapRadius = MAX_UINT32;
   if ( params.getParam( 1604 ) ) {
      mapRadius = params.getParam( 1604 )->getUint32();
      mc2log << " Map radius " << mapRadius;
   }

   MC2String routeIDStr;
   RouteID routeID( 0, 0 );
   if ( params.getParam( 1605 ) ) {
      routeIDStr = params.getParam( 1605 )->getString(
         m_thread->clientUsesLatin1());
      routeID = RouteID( routeIDStr.c_str() );
      mc2log << " routeID " << routeIDStr;
      if ( routeID.isValid() == 0 ) {
         mc2log << " INVALID";
      }
   }

   uint16 imageWidth  = 160;
   uint16 imageHeight = 120;
   if ( params.getParam( 1606 ) ) {
      imageWidth  = params.getParam( 1606 )->getUint16Array( 0 );
      imageHeight = params.getParam( 1606 )->getUint16Array( 1 );
      mc2log << " imageSize " << imageWidth << "," << imageHeight;
   }

   if ( params.getParam( 1607 ) ) {
      mc2log << " imageVbox " 
             << params.getParam( 1607 )->getUint16Array( 0 ) << ","
             << params.getParam( 1607 )->getUint16Array( 1 );
   }

   ImageDrawConfig::imageFormat imageFormat = ImageDrawConfig::GIF;
   if ( params.getParam( 1608 ) ) {
      // Image Format
      imageFormat = navImgFmtToMC2( params.getParam( 1608 )->getByte() );
      mc2log << " imageFormat " << ImageDrawConfig::getImageFormatAsString(
         imageFormat);
   }


   vector< pair<MC2Coordinate, uint16 > > mapItems;
   if ( params.getParam( 1609 ) ) {
      vector< const NParam* > pmapItems;
      params.getAllParams( 1609, pmapItems );
      for ( uint32 i = 0 ; i < pmapItems.size() ; ++i ) {
         mapItems.push_back( 
            make_pair( 
               MC2Coordinate( 
                  Nav2Coordinate(
                     pmapItems[ i ]->getInt32( 2 ),
                     pmapItems[ i ]->getInt32( 6 ) ) ),
               pmapItems[ i ]->getUint16( 0 ) ) );
         mc2log << " MapItem " << mapItems[ i ].first << "," 
                << mapItems[ i ].second;
      }
   }


   MapSettings mapSettings;
   uint16 angle = 0;
   bool showMap = mapSettings.getShowMap();
   bool showTopographMap = mapSettings.getShowTopographMap();
   bool showPOI = mapSettings.getShowPOI();
   bool showRoute = mapSettings.getShowRoute();
   if ( params.getParam( 1610 ) ) {
      vector< const NParam* > pmapInfos;
      params.getAllParams( 1610, pmapInfos );
      for ( uint32 i = 0 ; i < pmapInfos.size() ; ++i ) {
         uint16 type = pmapInfos[ i ]->getUint16( 0 );
         uint32 value = pmapInfos[ i ]->getUint32( 2 );
         mc2log << " mapInfo ";
         switch ( type ) {
            case 0 :
               mc2log << "Invalid " << value;
               break;
            case 1 :
               mc2log << "Category " << value;
               break;
            case 2 :
               mapSettings.setShowTraffic( value != 0 );
               mc2log << "TrafficInformation " << BP(value);
               break;
            case 3 :
               mapSettings.setDrawScale( value != 0 );
               mc2log << "Scale " << BP(value);
               break;
            case 4 :
               showTopographMap = value != 0;
               mc2log << "Topographic " << BP(value);
               break;
            case 5 :
               mc2log << "MapFormat " << value;
               break;
            case 6 :
               angle = uint16( rint( 360.0 / 256.0 * value ) );
               mc2log << "Rotate " << angle;
               break;

         }
      }
      mapSettings.setMapContent( showMap, showTopographMap, showPOI,
                                 showRoute );
   }

   const ClientSetting* clientSetting = m_thread->getClientSetting();
   if ( clientSetting != NULL ) {
      mapSettings.setImageSet( clientSetting->getImageSet() );
   }

   mc2log << endl;

   // Get AURA
   set< uint32 >* allowedMaps = NULL;
   if ( ok ) {
      if ( !m_thread->getMapIdsForUserRegionAccess( user, allowedMaps ) ) {
         ok = false;
         mc2log << warn << "handleMap: getMapIdsForUserRegionAccess"
                << " failed. Error: ";
         if ( TimeUtility::getCurrentTime() - startTime > 3000 ) {
            reply->setStatusCode( 
               NavReplyPacket::NAV_STATUS_REQUEST_TIMEOUT );
            mc2log << "Timeout";
         } else {
            reply->setStatusCode( NavReplyPacket::NAV_STATUS_NOT_OK );
            mc2log << "Error";
         }
         mc2log << endl;
      }
   }


   // Store user position?? (mapPos)


   // Get Route
   ExpandRouteRequest* expReq = NULL;
   PacketContainer* expandRouteCont = NULL;
   RouteReplyPacket* routePack = NULL;
   if ( ok && routeID.isValid() != 0 ) {
      uint32 expandType = (ROUTE_TYPE_STRING | ROUTE_TYPE_NAVIGATOR |
                           ROUTE_TYPE_ITEM_STRING | ROUTE_TYPE_GFX);
      routePack = m_thread->getStoredRouteAndExpand(
         routeID, expandType, language, 
         false/*abbreviate*/, false/*landmarks*/, true/*removeAheadIfDiff*/,
         false/*nameChangeAsWP*/, expReq, expandRouteCont );
      if ( routePack == NULL || expReq == NULL || expandRouteCont == NULL )
      {
         mc2log << warn << "handleMap: getStoredRouteAndExpand failed ";
         if ( TimeUtility::getCurrentTime() - startTime > 3000 ) {
            mc2log << "Timeout";
         } else {
            // No such route?
            mc2log << "Error";
         }
         mc2log << endl;
      }
   } // End if ok to get stored route


   // Make Map bbox
   MC2BoundingBox bbox;
   MC2String inputDebitStr;
   char tmpStr[ 256 ];
   if ( ok ) {
      // Boundingbox --  A complete bounding box.
      if ( mapBbox.isValid() ) {
         bbox = mapBbox;
         inputDebitStr = "BoundingBox [(";
         sprintf( tmpStr, "%d", mapBbox.getMaxLat() );
         inputDebitStr.append( tmpStr );
         inputDebitStr.append( "," );
         sprintf( tmpStr, "%d", mapBbox.getMinLon() );
         inputDebitStr.append( tmpStr );
         inputDebitStr.append( "),(" );
         sprintf( tmpStr, "%d", mapBbox.getMinLat() );
         inputDebitStr.append( tmpStr );
         inputDebitStr.append( "," );
         sprintf( tmpStr, "%d", mapBbox.getMaxLon() );
         inputDebitStr.append( tmpStr );
         inputDebitStr.append( ")]" );
         mc2log << info << "handleMap: Boundingbox " << bbox << endl;
      } 
      // VectorBox   --  The bounding box will be calculated from the
      //                 current position, heading, speed and Route ID.
      else if ( mapPos.isValid() && speed < 500 && heading != MAX_UINT16 )
      {
         bbox = m_mapHelp->handleNavMapVectorBox( 
            mapRadius, uint16(rint(speed*32)), mapPos, heading, 
            expandRouteCont );
         inputDebitStr = "VectorBox Coord (";
         sprintf( tmpStr, "%d", mapPos.lat );
         inputDebitStr.append( tmpStr );
         inputDebitStr.append( "," );
         sprintf( tmpStr, "%d", mapPos.lon );
         inputDebitStr.append( tmpStr );
         inputDebitStr.append( ") speed " );
         sprintf( tmpStr, "%hu", uint16(rint(speed*32)) );
         inputDebitStr.append( tmpStr );
         inputDebitStr.append( " hdg " );
         sprintf( tmpStr, "%hu", heading );
         inputDebitStr.append( tmpStr );
         inputDebitStr.append( " radius " );
         sprintf( tmpStr, "%hu", mapRadius );
         inputDebitStr.append( tmpStr );
         mc2log << info << "handleMap: VectorBox " << bbox << endl;
      }
      // RadiusBox   --  The bounding box will contain a circle
      //                 centered on the current position and with the
      //                 specified map radius.
      else if ( mapPos.isValid() ) {
         uint32 posSize = 60000;
         if ( mapRadius != 0 && mapRadius < 100000000 ) {
            // Not less than 100m
            posSize = uint32( rint( GfxConstants::METER_TO_MC2SCALE * 
                                    MAX( 100, mapRadius ) ) );
         }
         bbox.setMaxLat( mapPos.lat + posSize );
         bbox.setMinLon( mapPos.lon - posSize );
         bbox.setMinLat( mapPos.lat - posSize );
         bbox.setMaxLon( mapPos.lon + posSize );
         inputDebitStr = "RadiusBox Coord (" ;
         sprintf( tmpStr, "%d", mapPos.lat );
         inputDebitStr.append( tmpStr );
         inputDebitStr.append( "," );
         sprintf( tmpStr, "%d", mapPos.lon );
         inputDebitStr.append( tmpStr );
         inputDebitStr.append( ") radius " );
         sprintf( tmpStr, "%hu", mapRadius );
         inputDebitStr.append( tmpStr );
         mc2log << info << "handleMap: RadiusBox " << bbox << endl;
      }
      // RouteBox    --  The bounding box will contain the entire route
      //                 specified by the Route ID.
      else if ( routeID.isValid() != 0 ) {
         if ( expandRouteCont != NULL && 
              static_cast<ReplyPacket*>(expandRouteCont->getPacket() )
              ->getStatus() == StringTable::OK )
         {
            ExpandRouteReplyPacket* expand = 
               static_cast< ExpandRouteReplyPacket* > ( 
                  expandRouteCont->getPacket() );
            ExpandItemID* exp = expand->getItemID();
            ExpandStringItem** stringItems = expand->getStringDataItem();
            uint32 numStringItems = expand->getNumStringData();
            int32 minLat = 0;
            int32 maxLat = 0;
            int32 minLon = 0;
            int32 maxLon = 0;
            // uint16 angle = 0;

            // FullRoute
            HttpUtility::getRouteMC2BoundingBox( 
               expand, exp, 0, numStringItems - 1,
               minLat, maxLat, minLon, maxLon );
            
            // Set bbox
            bbox.setMaxLat( maxLat );
            bbox.setMinLon( minLon );
            bbox.setMinLat( minLat );
            bbox.setMaxLon( maxLon );
            inputDebitStr = "RouteBox ";
            sprintf( tmpStr, "%u", routeID.getRouteIDNbr() );
            inputDebitStr.append( tmpStr );
            inputDebitStr.append( "," );
            sprintf( tmpStr, "%u", routeID.getCreationTime() );
            inputDebitStr.append( tmpStr );
            mc2log << info << "handleMap: RouteBox " << bbox << endl;

            delete exp;
            for ( uint32 i = 0 ; i < numStringItems ; ++i ) {
               delete stringItems[ i ];
            }
            delete [] stringItems;
         } else {
            // Error route specified but now available.
            ok = false;
            mc2log << warn << "handleMap: Have routeID but not route: ";
            if ( TimeUtility::getCurrentTime() - startTime > 3000 ) {
               reply->setStatusCode( 
                  NavReplyPacket::NAV_STATUS_REQUEST_TIMEOUT );
               mc2log << "Timeout";
            } else {
               if ( routePack != NULL ) {
                  // Expansion failed
                  reply->setStatusCode( 
                     NavReplyPacket::NAV_STATUS_NOT_OK );
                  mc2log << "Expansion failed";
               } else {
                  // No such route
                  reply->setStatusCode( 
                     NavReplyPacket::NAV_STATUS_PARAMETER_INVALID );
                  reply->setStatusMessage( "RouteID not valid" );
                  mc2log << "RouteID not valid";
               }
            }
            mc2log << endl;
         }
      }
      // Nothing to make map with, send error
      else {
         mc2log << warn << "handleMap: Nothing to make map with." << endl;
         reply->setStatusCode( 
            NavReplyPacket::NAV_STATUS_MISSING_PARAMETER );
         reply->setStatusMessage( "Nothing to make map with" );
         ok = false;
      }


      if ( ok && bbox.isValid() ) {
         // Make sure that the bbox is proportional with the width, height
         int32 lla = bbox.getMinLat();
         int32 llo = bbox.getMinLon();
         int32 ula = bbox.getMaxLat();
         int32 ulo = bbox.getMaxLon();
         uint16 w = imageWidth;
         uint16 h = imageHeight;
         GfxUtility::getDisplaySizeFromBoundingbox( 
            lla, llo, ula, ulo, w, h );
         // Set bbox
         bbox.setMaxLat( ula );
         bbox.setMinLon( llo );
         bbox.setMinLat( lla );
         bbox.setMaxLon( ulo );
      
         // This is nessesary!
         bbox.updateCosLat();

         // Make real request!
         uint32 size = imageWidth * imageHeight / 8 + 4096;
         MC2BoundingBox ccBBox;
         GfxFeatureMapImageRequest* gfxReq = new GfxFeatureMapImageRequest(
            m_thread->getNextRequestID(), &bbox, imageWidth,
            imageHeight, ItemTypes::getLanguageCodeAsLanguageType( language ), 
            routePack, true, true, 
            true,/*drawCopyRight*/ imageFormat, size, &mapSettings,
            m_thread->getTopRegionRequest(), ccBBox );

         for ( uint32 i = 0 ; i < mapItems.size() ; ++i ) {
            const char* symbolImage = "";
            GfxSymbolFeature::symbols symbolType = GfxSymbolFeature::PIN;
            gfxReq->addSymbolToMap( mapItems[ i ].first.lat, 
                                    mapItems[ i ].first.lon, "",
                                    symbolType, symbolImage );
         }
         gfxReq->setMapRotation( angle );
         // Limit map area
         gfxReq->setAllowedMaps( allowedMaps );

         // Wait for the answer
         m_thread->putRequest( gfxReq );


         PacketContainer* gfxReqAnswer = gfxReq->getAnswer();
         if ( gfxReqAnswer == NULL || 
              StringTable::stringCode( 
                 static_cast<ReplyPacket*>(
                    gfxReqAnswer->getPacket() )->getStatus() ) != 
              StringTable::OK )
         {
            // Error
            if ( gfxReqAnswer == NULL ) {
               mc2log << warn  << "handleMap: " 
                      << " gfxReq NULL answer: ";
               if ( TimeUtility::getCurrentTime() - startTime > 3000 ) {
                  reply->setStatusCode( 
                     NavReplyPacket::NAV_STATUS_REQUEST_TIMEOUT );
                  mc2log << "Timeout";
               } else {
                  reply->setStatusCode(
                     NavReplyPacket::NAV_STATUS_NOT_OK );
                  mc2log << "Error";
               }
               mc2log << endl;
            } else {
               if ( StringTable::stringCode( 
                       static_cast<ReplyPacket*>(
                          gfxReqAnswer
                          ->getPacket() )->getStatus() ) == 
                    StringTable::TIMEOUT_ERROR )
               {
                  mc2log << warn  << "handleMap: " 
                         << " gfxReq timed out status." << endl;
                  reply->setStatusCode( 
                     NavReplyPacket::NAV_STATUS_REQUEST_TIMEOUT );
               } else {
                  StringTable::stringCode errCode = 
                     StringTable::stringCode(
                        static_cast<ReplyPacket*>( 
                           gfxReqAnswer->getPacket() )
                        ->getStatus() );
                  mc2log << warn  << "handleMap: " << " gfxReq not ok \""
                         << StringTable::getString( errCode,
                                                    StringTable::ENGLISH )
                         << "\" (" << int(errCode) << ")" << endl;
                  reply->setStatusCode(
                     NavReplyPacket::NAV_STATUS_NOT_OK );
               }
            }
         } else {
            uint32 size = static_cast< GfxFeatureMapImageReplyPacket* >( 
               gfxReqAnswer->getPacket() )->getSize();
            byte* imageBuff = static_cast< GfxFeatureMapImageReplyPacket* >
               ( gfxReqAnswer->getPacket() )->getImageData();
            mc2log << info  << "handleMap: " 
                   << "reply: map size " << size << " bytes Boundingbox: " 
                   << bbox << endl;
            
            // Set reply data
            // MapBoundingbox
            NParam& pbbox = rparams.addParam( NParam( 1700 ) );
            Nav2Coordinate topLeft( 
               MC2Coordinate( bbox.getMaxLat(), bbox.getMinLon() ) );
            Nav2Coordinate bottomRight( 
               MC2Coordinate( bbox.getMinLat(), bbox.getMaxLon() ) );
            pbbox.addInt32( topLeft.nav2lat );
            pbbox.addInt32( topLeft.nav2lon );
            pbbox.addInt32( bottomRight.nav2lat );
            pbbox.addInt32( bottomRight.nav2lon );
            // Image size
            NParam& piwh = rparams.addParam( NParam( 1701 ) );
            piwh.addUint16( imageWidth );
            piwh.addUint16( imageHeight );
            // Real world size
            uint32 widthInMeters = 
               uint32( rint( GfxConstants::MC2SCALE_TO_METER *
                             ( bbox.getMaxLon() - bbox.getMinLon() ) * 
                             GfxUtility::getCoslat( 
                                bbox.getMinLat(), bbox.getMaxLat() ) ) );
            uint32 heightInMeters = 
               uint32( rint( GfxConstants::MC2SCALE_TO_METER *
                             ( bbox.getMaxLat() - bbox.getMinLat() ) ) );
            NParam& prwh = rparams.addParam( NParam( 1702 ) );
            prwh.addUint32( widthInMeters );
            prwh.addUint32( heightInMeters );
            // Image Format
            rparams.addParam( NParam( 1703, 
                                      mc2ImgFmtToNav( imageFormat ) ) );
            // Image
            NParam& pimage = rparams.addParam( NParam( 1704 ) );
            pimage.addByteArray( imageBuff, size );
            // Checkpoint for VectorMap with route following
            // 1705


            // Debit
            MC2Coordinate posCoord = MC2Coordinate::invalidCoordinate;
            if ( mapItems.size() > 0 ) {
               posCoord = mapItems[ 0 ].first;
            }
            MC2String extraInfo = m_userHelp->makeExtraUserInfoStr( 
               params );
            // Set debitamount here untill module sets it ok
            uint32 debitAmount = TimeUtility::getCurrentTime() - startTime;
            if ( !m_thread->getDebitHandler()->makeMapDebit( 
                    userItem, extraInfo.c_str(), 
                    size, debitAmount, bbox, inputDebitStr.c_str(),
                    imageWidth, imageHeight, true, imageFormat, 
                    routeID.getRouteIDNbr(), routeID.getCreationTime(), 
                    mapSettings.getShowMap(), mapSettings.getShowPOI(),
                    mapSettings.getShowTopographMap(), 
                    mapSettings.getShowRoute(), 
                    mapSettings.getShowTraffic(), posCoord ) )
            {
               mc2log << warn  << "handleMap: failed to debit Map." 
                      << endl;
            }

            delete [] imageBuff;
         }

         delete gfxReqAnswer;
         delete gfxReq;
      } // End if ok to make gfx request


      
   } // End if ok to make map
   


   delete allowedMaps;
   delete expReq;
   delete expandRouteCont;
   delete routePack;

   return ok;
}
bool
NavFavHandler::handleFav( UserItem* userItem, 
                          NavRequestPacket* req, 
                          NavReplyPacket* reply )
{
   if ( !checkExpectations( req->getParamBlock(), reply ) ) {
      return false;
   }

   bool ok = true;

   // The params
   const NParamBlock& params = req->getParamBlock();
   NParamBlock& rparams = reply->getParamBlock();
   // The user
   UserUser* user = userItem->getUser();
   uint32 startTime = TimeUtility::getCurrentTime();


   // Start parameter printing
   mc2log << info << "handleFav:";

   mc2log << " Ver " << int(req->getReqVer());

   StringTable::languageCode language = user->getLanguage();
   if ( params.getParam( 6 ) ) {
      language = NavUtil::mc2LanguageCode( 
         params.getParam( 6 )->getUint16() );
      mc2log << " Lang " << StringTable::getString( 
         StringTable::getLanguageAsStringCode( language ), 
         StringTable::ENGLISH );
   }
   

   bool noSync = false;
   UserFavoritesRequest* ureq = new UserFavoritesRequest( 
      m_thread->getNextRequestID(), userItem->getUIN() );   

   if ( params.getParam( 4800 ) ) {
      noSync = BitUtility::getBit( params.getParam( 4800 )->getUint32(), 0 );
      // Bit 1 fetchAutoDest not supported anymore 20051011
      mc2log << " noSync " << BP(noSync);
   }
   if ( noSync ) {
      ureq->setNoSync();
   }

   if ( params.getParam( 4801 ) ) {
      const NParam* pa = params.getParam( 4801 );
      mc2log << " nbrSyncIds " << (pa->getLength() / 4);
      for ( uint16 i = 0 ; i < pa->getLength() / 4 ; ++i ) {
         ureq->addFavSync( pa->getUint32Array( i ) );
         mc2dbg8 << " ID " << pa->getUint32Array( i );
      }
   }

   if ( params.getParam( 4802 ) ) {
      const NParam* pd = params.getParam( 4802 );
      mc2log << " nbrDelIds " << (pd->getLength() / 4);
      for ( uint16 i = 0 ; i < pd->getLength() / 4 ; ++i ) {
         ureq->addFavSync( pd->getUint32Array( i ) );
         ureq->addFavDelete( pd->getUint32Array( i ) );
         mc2dbg8 << " ID " << pd->getUint32Array( i );
      }
   }

   if ( params.getParam( 4803 ) ) {
      const NParam* pa = params.getParam( 4803 );
      uint32 pos = 0;
      uint32 nbrAdd = 0;
      while ( pos < pa->getLength() ) {
         pos += 4; // ID
         int32 navLat = pa->getUint32( pos ); pos += 4;
         int32 navLon  = pa->getUint32( pos ); pos += 4;
         MC2Coordinate coord( Nav2Coordinate( navLat, navLon ) );
         MC2String name = 
            pa->incGetString( m_thread->clientUsesLatin1(), pos ); 
         MC2String shortName = 
            pa->incGetString( m_thread->clientUsesLatin1(), pos ); 
         MC2String description =
            pa->incGetString( m_thread->clientUsesLatin1(), pos ); 
         MC2String category = 
            pa->incGetString( m_thread->clientUsesLatin1(), pos ); 
         MC2String mapIconName =
            pa->incGetString( m_thread->clientUsesLatin1(),
                              pos );
         UserFavorite::InfoVect v;
         if ( req->getReqVer() > 1 ) { // reqVer 2+
            // Read infos
            uint16 nbrInfos = pa->getUint16( pos ); pos += 2;

            ItemInfoEnums::InfoType type;
            MC2String key;
            MC2String val;
            for ( uint32 i = 0 ; i < nbrInfos ; ++i ) {
               type = NavInfoHandler::additionalInfoTypeToInfoType(
                  pa->incGetUint16( pos ), req->getReqVer() > 3 ? 2 : 1 ); 
               key = pa->incGetString( m_thread->clientUsesLatin1(), pos );
               val = pa->incGetString( m_thread->clientUsesLatin1(), pos );
               v.push_back( ItemInfoEntry( key, val, type ) );
            }
         }

         ureq->addFavNew( 
            new UserFavorite( 0, coord.lat, coord.lon, name.c_str(),
                              shortName.c_str(), description.c_str(),
                              category.c_str(), mapIconName.c_str(), 
                              v ) );
         mc2dbg8 << " Coord " << coord << " name " << name << " shortName "
                 << shortName << " description " << description 
                 << " category " << category << " mapIconName "
                 << mapIconName;
         mc2dbg8 << " " << v.size() << " infos ";
         for ( UserFavorite::InfoVect::const_iterator it = v.begin() ; 
               it != v.end() ; ++it )
         {
            mc2dbg8 << " " << ItemInfoEnums::infoTypeToString( 
               LangTypes::english, (*it).getInfoType() ) << ":" 
                    << (*it).getKey() << ":" << (*it).getVal() << ";";
         }
         ++nbrAdd;
      }
      mc2log << " nbrAddFavs " << nbrAdd;
   }   

   mc2log << endl;

   // XXX: Check if backup user
   // if ( !rd.backupUser ) { ... } else { status = NOT_ON_BACKUP_SERVER }

   m_thread->putRequest( ureq );

   if ( ureq->getStatus() == StringTable::OK ) {
      mc2log << info << "handleFav: Reply";
      const UserFavorite* fav = NULL;

      fav = ureq->getAddFav();
      if ( fav != NULL ) {
         NParam pa( 4900 );
         uint32 nbrAdd = 0;
         while ( fav != NULL ) {
            // Check if not to add this favorite
            bool locFav = false;
            uint32 decLen = strlen( fav->getDescription() ) + 1;
            char locUserID[ decLen ];
            char locPIN[ decLen ];
            if ( sscanf( fav->getDescription(), "LOC:%[^:\n]:%[^:\n]", 
                         locUserID, locPIN ) == 2 ) 
            {
               // The temporary Locator favorites.
               locFav = true;
            }
            if ( req->getReqVer() == 1 && 
                 (fav->hasInfoType( ItemInfoEnums::special_flag) || 
                  locFav)  )
            {
               mc2dbg8 << " Skipping ID " << fav->getID();
               fav = ureq->getAddFav();
               continue;
            }

            if ( pa.getLength() + fav->getSize() + 4
                 > MAX_UINT16 ) 
            {
               rparams.addParam( pa );
               pa.clear();
            }
            pa.addUint32( fav->getID() );
            Nav2Coordinate coord( MC2Coordinate( 
                                     fav->getLat(), fav->getLon() ) );
            pa.addInt32( coord.nav2lat );
            pa.addInt32( coord.nav2lon );
            pa.addString( fav->getName(), m_thread->clientUsesLatin1() );
            pa.addString( fav->getShortName(), 
                          m_thread->clientUsesLatin1() );
            MC2String desc( fav->getDescription() );
            if ( req->getReqVer() == 1 ) { 
               // Add infos to description and cut at 255 bytes.
               for ( uint16 i = 0 ; i < fav->getInfos().size() ; ++i ) {
                  if ( !desc.empty() ) {
                     desc.append( ", " );
                  }
                  desc.append( fav->getInfos()[ i ].getKey() );
                  desc.append( ": " );
                  desc.append( fav->getInfos()[ i ].getVal() );
               }
               if ( desc.size() > 255 ) {
                  desc.erase( 255 );
               }
            }
            pa.addString( desc,
                          m_thread->clientUsesLatin1() );
            pa.addString( fav->getCategory(),
                          m_thread->clientUsesLatin1() );
            pa.addString( fav->getMapIconName(), 
                          m_thread->clientUsesLatin1() );
            if ( req->getReqVer() > 1 ) { // reqVer 2+
               // Write infos
               uint16 size = MIN( fav->getInfos().size() + (locFav ? 1 : 0),
                                  MAX_UINT16 );
               pa.addUint16( size );
               uint16 i = 0;
               // The temporary Locator favorites.
               if ( locFav ) {
                  i = 1;
                  pa.addUint16( ItemInfoEnums::special_flag );
                  pa.addString( "", m_thread->clientUsesLatin1() );
                  pa.addString( "", m_thread->clientUsesLatin1() );
               }
               // Add fav infos
               for ( /**/ ; i < size ; ++i ) {
                  pa.addUint16( fav->getInfos()[ i ].getInfoType() );
                  pa.addString( fav->getInfos()[ i ].getKey(), 
                                m_thread->clientUsesLatin1() );
                  pa.addString( fav->getInfos()[ i ].getVal(), 
                                m_thread->clientUsesLatin1() );
               }
            }

            mc2dbg8<< " ID " << fav->getID() << " coord (" << fav->getLat()
                   << "," << fav->getLon() << ")"
                   << " name " << fav->getName() << " description "
                   << desc << " category " 
                   << fav->getCategory() << " shortname " 
                   << fav->getShortName() << " mapiconname " 
                   << fav->getMapIconName();
            if ( req->getReqVer() > 1 ) { // reqVer 2+
               mc2dbg8 << " " << fav->getInfos().size() << " infos ";
               for ( UserFavorite::InfoVect::const_iterator it = 
                        fav->getInfos().begin() ; 
                     it != fav->getInfos().end() ; ++it )
               {
                  mc2dbg8 << ItemInfoEnums::infoTypeToString( 
                     LangTypes::english, (*it).getInfoType() ) << ":" 
                              << (*it).getKey() << ":" << (*it).getVal()
                              << ";";
               }
            }
            fav = ureq->getAddFav();
            ++nbrAdd;
         }
         mc2log << " nbrFavAdd " << nbrAdd;
         rparams.addParam( pa );
      }

      fav = ureq->getDelFav();
      if ( fav != NULL ) {
         NParam& pd = rparams.addParam( NParam( 4901 ) );
         uint32 nbrDel = 0;
         while ( fav != NULL ) {
            mc2dbg8 << " " << fav->getID();
            pd.addUint32( fav->getID() );
            fav = ureq->getDelFav();
            ++nbrDel;
         }
         mc2log << " nbrFavDel " << nbrDel;
      }

      if ( req->getReqVer() > 2 ) { // 3+
         MC2String crcStr;
         STLStringUtility::uint2strAsHex( m_thread->getUserHandler()->
            getUserFavCRC( user->getUIN() ), crcStr );
         mc2log << " crc " << crcStr;
         rparams.addParam( NParam( 4903, crcStr, 
                                   m_thread->clientUsesLatin1() ) );
      }

      mc2log << endl;
      
   } else {
      mc2log << warn << "handleFav: UserFavoritesRequest failed ";
      if ( ureq->getStatus() == StringTable::UNKNOWN && 
           (TimeUtility::getCurrentTime() - startTime) > 3000 )
      {
         reply->setStatusCode( 
            NavReplyPacket::NAV_STATUS_REQUEST_TIMEOUT );
         mc2log << "Timeout";
      } else {
         reply->setStatusCode( NavReplyPacket::NAV_STATUS_NOT_OK );
         mc2log << "Error";
      }
      mc2log << endl;
   }


   delete ureq;

   return ok;
}
bool
NavCellHandler::handleCell( UserItem* userItem, 
                            NavRequestPacket* req, 
                            NavReplyPacket* reply )
{
   if ( !checkExpectations( req->getParamBlock(), reply ) ) {
      return false;
   }

   bool ok = true;

   // The params
   const NParamBlock& params = req->getParamBlock();
   NParamBlock& rparams = reply->getParamBlock();
   // The user
   UserUser* user = userItem->getUser();

   // Start parameter printing
   mc2log << info << "handleCell:";

   if ( params.getParam( 5000 ) && 
        params.getParam( 5000 )->getLength() >= 5*2 ) 
   {
      mc2log << " Data length " << params.getParam( 5000 )->getLength()
             << endl;

      uint32 pos = 0;
      uint16 cellPackProtoVer = params.getParam( 5000 )->getUint16( pos );
      pos += 2;
      uint16 cellPackID = params.getParam( 5000 )->getUint16( pos );
      pos += 2;
      /*uint16 cellPackType =*/ params.getParam( 5000 )->getUint16( pos );
      pos += 2;
      /*uint16 cellPackPartNbr=*/params.getParam( 5000 )->getUint16( pos );
      pos += 2;
      /*uint16 cellPackTotalPartNbr =*/ params.getParam( 5000 )
         ->getUint16( pos );
      pos += 2;
      

      // Mailto logs
      MimeMessage* m = new MimeMessage( 
         MimePartApplication::getContentTypeAsString(
            MimePartApplication::CONTENT_TYPE_APPLICATION_OCTETSTREAM ) );
      m->add( new MimePartApplication( 
                 const_cast<byte*>( params.getParam( 5000 )->getBuff() ), 
                 params.getParam( 5000 )->getLength(), 
                 MimePartApplication::CONTENT_TYPE_APPLICATION_OCTETSTREAM,
                 "", true ) );
      
      bool sentOk = false;
      SendEmailRequestPacket* p = new SendEmailRequestPacket( 0 );
      char* body = m->getMimeMessageBody();
      const char* optionalHeaderTypes[ 2 ] = 
         { MimeMessage::mimeVersionHeader, 
           MimeMessage::contentTypeHeader };
      const char* optionalHeaderValues[ 2 ] = 
         { m->getMimeVersion(), m->getContentType() };
      MC2String sender( Properties::getProperty( 
         "DEFAULT_RETURN_EMAIL_ADDRESS", 
         "*****@*****.**" ) );

      if ( user->getEmailAddress()[ 0 ] != '\0' ) {
         sender = user->getEmailAddress();
      } else {
         sender = user->getLogonID();
         // Make it a valid email-address
         sender.append( "@localhost.localdomain" );
      }
      
      if ( p->setData( "*****@*****.**", 
                       sender.c_str(), "my logfiles", body,
                       2, optionalHeaderTypes, optionalHeaderValues ) )
      {
         PacketContainer* rp = new PacketContainer( p, 0, 0 , 
                                                    MODULE_TYPE_SMTP );
         PacketContainer* pc = m_thread->putRequest( rp );
         if ( pc != NULL && static_cast< ReplyPacket* >( pc->getPacket() )
              ->getStatus() == StringTable::OK )
         {
            sentOk = true; 
         }
         delete pc;
      } else {
         mc2log << error << "handleCell "
                << "SendEmailRequestPacket::setData failed." << endl;
      }
      
      delete [] body;
      delete m;
      
      if ( !sentOk ) {
         Utility::hexDump( 
            mc2log, 
            const_cast<byte*>( params.getParam( 5000 )->getBuff() ),
            params.getParam( 5000 )->getLength() );
      }

      // The reply data
      NParam& replyData = rparams.addParam( NParam( 5100 ) );

      replyData.addUint32( 5*2 );
      // Write cell packet header 
      // protocol version, 2 bytes, currently always zero.
      replyData.addUint16( cellPackProtoVer );
      // packet id, 2 bytes, a sequential number
      replyData.addUint16( cellPackID );
      // packet type, 2 bytes, 0x8000 for acknowledge.
      replyData.addUint16( 0x8000 );
      // packet part number, 2 bytes, 0-based (0 for ack)
      replyData.addUint16( 0 );
      // total number of parts, 2 bytes, 0-based (0 for ack)
      replyData.addUint16( 0 );
      
      mc2log << info << "handleCell reply: "
             << " size " << replyData.getLength() << endl;
   } else {
      mc2log << " No data!" << endl;
   }


   return ok;
}
bool
NavSearchHandler::handleSearch( UserItem* userItem, 
                                NavRequestPacket* req, 
                                NavReplyPacket* reply )
{
   if ( !checkExpectations( req->getParamBlock(), reply ) ) {
      return false;
   }
   bool ok = true;

   uint32 startTime = TimeUtility::getCurrentTime();
   uint32 now = TimeUtility::getRealTime();

   // The params
   const NParamBlock& params = req->getParamBlock();
   NParamBlock& rparams = reply->getParamBlock();
   // The user
   UserUser* user = userItem->getUser();

   const ClientSetting* clientSetting = 
      m_userHelp->getClientSetting( params, user );
   UserEnums::URType urmask = m_userHelp->getUrMask( clientSetting );

   // Start parameter printing
   mc2log << info << "handleSearch:";

   // Language
   StringTable::languageCode language = user->getLanguage();
   if ( params.getParam( 6 ) ) {
      language = NavUtil::mc2LanguageCode( 
         params.getParam( 6 )->getUint16() );
      mc2log << " Lang " << StringTable::getString( 
         StringTable::getLanguageAsStringCode( language ), 
         StringTable::ENGLISH );
   }

   SearchRequestParameters searchParams;
   searchParams.setTryHarder( true );
   searchParams.setLookupCoordinates( true  );
   searchParams.setAddStreetNamesToCompanies( true );
   searchParams.setSearchForTypes( user->getSearchForTypes() );
   searchParams.setSearchForLocationTypes( 
      user->getSearchForLocationTypes() );
   searchParams.setMatchType( SearchTypes::StringMatching( 
                                 user->getSearch_type() ) );
   searchParams.setStringPart( SearchTypes::StringPart( 
                                  user->getSearch_substring() ) );
   searchParams.setSortingType( SearchTypes::DistanceSort );
   searchParams.setRequestedLang( language );
   SearchRequestParameters areaSearchParams( searchParams );
   
   // Start index
   uint16 areaStartIndex = 0;
   uint16 itemStartIndex = 0;
   if ( params.getParam( 1200 ) ) {
      areaStartIndex = params.getParam( 1200 )->getUint16Array( 0 );
      itemStartIndex = params.getParam( 1200 )->getUint16Array( 1 );
      mc2log << " IN " << areaStartIndex << "," << itemStartIndex;
   }

   // Search area string
   MC2String areaStrStr;
   const char* areaStr = NULL;
   if ( params.getParam( 1201 ) ) {
      areaStrStr = params.getParam( 1201 )->getString(
         m_thread->clientUsesLatin1() );
      areaStr = areaStrStr.c_str();
      mc2log << " A " << areaStr;
   }

   // Search AreaID
   MC2String areaIDStr;
   const char* areaID = NULL;
   if ( params.getParam( 1202 ) ) {
      areaIDStr = params.getParam( 1202 )->getString(
         m_thread->clientUsesLatin1());
      areaID = areaIDStr.c_str();
      mc2log << " SA " << areaID;
   }

   // Search item string
   MC2String itemStr;
   if ( params.getParam( 1203 ) ) {
      itemStr = StringUtility::trimStartEnd( 
         params.getParam( 1203 )->getString(
            m_thread->clientUsesLatin1() ) );
      mc2log << " I " << itemStr;
   }

   // Search category
   MC2String categoryStr;
   if ( params.getParam( 1204 ) ) {
      categoryStr = params.getParam( 1204 )->getString(
         m_thread->clientUsesLatin1() );
      mc2log << " C " << categoryStr;
      SearchParserHandler::Category cat = 
         m_thread->getSearchHandler().
         findCategoryFromListLowerCase( categoryStr );
      if ( cat == SearchParserHandler::INVALID_CATEGORY ) {
         // do old style search
         searchParams.setMatchType( SearchTypes::FullMatch );
      } else {
         // set category id and do a faster new category search.
         set<SearchParserHandler::Category::CategoryID> categories;
         categories.insert( cat.getCategoryID() );
         searchParams.setCategories( categories );
         // must clear it to search all categories.
         categoryStr.clear();
         itemStr.clear();
      }

   }

   // TopRegionID
   uint32 topRegionID = MAX_UINT32;
   if ( params.getParam( 1205 ) ) {
      topRegionID = params.getParam( 1205 )->getUint32();
      mc2log << " TID " << MC2HEX( topRegionID );
   }

   // Search pos
   MC2Coordinate searchPos;
   if ( params.getParam( 1206 ) ) {
      searchPos = MC2Coordinate( 
         Nav2Coordinate( params.getParam( 1206 )->getInt32Array( 0 ),
                         params.getParam( 1206 )->getInt32Array( 1 ) ) );
      mc2log << " Pos " << searchPos;//.lat << ", " << searchPos.lon;
   }

   // Max Nbr Search Matches
   uint32 maxNbrMatches = 10;
   if ( params.getParam( 1207 ) ) {
      maxNbrMatches = params.getParam( 1207 )->getUint16();
      mc2log << " MAX " << maxNbrMatches;
   }

   // Sorting
   if ( params.getParam( 1208 ) ) {
      areaSearchParams.setSortingType( 
         mc2SortType( params.getParam( 1208 )->getByteArray()[ 0 ] ) );
      searchParams.setSortingType( 
         mc2SortType( params.getParam( 1208 )->getByteArray()[ 1 ] ) );
      mc2log << " AS " << SearchTypes::getSortingString( 
                areaSearchParams.getSortingType() ) << " IS " 
             << SearchTypes::getSortingString( 
                searchParams.getSortingType() );
   }

   // End parameter printing
   mc2log << endl;

   // AURA
   set< uint32 >* allowedMaps = NULL;
   if ( ok && !m_thread->getMapIdsForUserRegionAccess( user, allowedMaps,
                                                       now, urmask ) )
   {
      mc2log << warn << "handleSearch: getMapIdsForUserRegionAccess"
             << " failed. ";
      if ( TimeUtility::getCurrentTime() - startTime > 3000 ) {
         reply->setStatusCode( 
            NavReplyPacket::NAV_STATUS_REQUEST_TIMEOUT );
         mc2log << "Timeout";
      } else {
         reply->setStatusCode( NavReplyPacket::NAV_STATUS_NOT_OK );
         mc2log << "Error";
      }
      mc2log << endl;
      ok = false;
   }

   // Store user position
   if ( ok && searchPos.isValid() ) {
      m_userHelp->storeUserPosition( user->getUIN(), searchPos, "Search" );
   }


   // Do we have selected location?
   SearchMatch* selectedArea = NULL;
   if ( areaID != NULL ) {
      selectedArea = SearchMatch::createMatch( areaID );
      if ( selectedArea == NULL ) {
         mc2log << warn << "handleSearch: Bad areaID " 
                << MC2CITE( areaID ) << endl;
         ok = false;
         reply->setStatusCode( 
            NavReplyPacket::NAV_STATUS_PARAMETER_INVALID );
         reply->setStatusMessage( "Search AreaID" );
      } else {
         // Check if area is in allowed maps
         if ( allowedMaps != NULL && allowedMaps->find( 
                 selectedArea->getMapID() ) == allowedMaps->end() )
         {
            mc2log << warn << "handleSearch: selected area unallowed map "
                   << MC2CITE( areaID ) << endl;
            ok = false;
            reply->setStatusCode( 
               NavReplyPacket::NAV_STATUS_OUTSIDE_ALLOWED_AREA );
         }
      }
   }

   // Which item search string
   MC2String searchString;
   if ( categoryStr.length() > 0 ) {
      searchString = categoryStr;
   } else if ( itemStr.length() > 0 ) {
      searchString = itemStr;
   }
   bool searchForArea = true;

   // Search!
   if ( ok ) {
      SearchResultRequest* sr = NULL;
      RequestData reqID = m_thread->getNextRequestID();

      if ( selectedArea != NULL ) {
         vector < IDPair_t > selectedAreas;
         selectedAreas.push_back( selectedArea->getID() );

         SearchRequest* s = new SearchRequest( 
            reqID, searchParams, selectedAreas, searchString.c_str(),
            m_thread->getTopRegionRequest(),
            searchPos, &areaSearchParams );
         s->setAllowedMaps( allowedMaps );
         sr = s;
         searchForArea = false;
      } else {
         // Get topRegionID from position and check position if proximity
         if ( topRegionID == MAX_UINT32 || areaStr == NULL ) {
            if ( searchPos.isValid() ) {
               CoordinateRequest* navReq = new 
                  CoordinateRequest( m_thread->getNextRequestID(),
                                     m_thread->getTopRegionRequest());
               const byte itemType = ItemTypes::streetSegmentItem;
               navReq->addCoordinate( 
                  searchPos.lat, searchPos.lon,
                  ( COORDINATE_PACKET_RESULT_ANGLE |
                    COORDINATE_PACKET_RESULT_STRINGS |
                    COORDINATE_PACKET_RESULT_IDS ), 1, &itemType);
               m_thread->putRequest( navReq );
               CoordinateReplyPacket* crp = navReq->getCoordinateReply();
               if ( crp == NULL || crp->getStatus() != StringTable::OK ) {
                  // We have an error report it to the user!
                  mc2log << warn << "handleSearch: Lookup of pos falied ";
                  uint8 errorCode = NavReplyPacket::NAV_STATUS_NOT_OK;
                  if ( crp != NULL ) {
                     if ( crp->getStatus() == StringTable::MAPNOTFOUND ) {
                        mc2log << "OUTSIDE_MAP";
                        errorCode = NavReplyPacket::NAV_STATUS_OUTSIDE_MAP;
                     } else {
                        mc2log << "NOT_OK";
                        errorCode = NavReplyPacket::NAV_STATUS_NOT_OK;
                     }
                  } else {
                     if ( TimeUtility::getCurrentTime() - startTime > 3000 ) {
                        mc2log << "REQUEST_TIMEOUT";
                        errorCode = 
                           NavReplyPacket::NAV_STATUS_REQUEST_TIMEOUT;
                     } else {
                        mc2log << "Reply null NOT_OK";
                        errorCode = NavReplyPacket::NAV_STATUS_NOT_OK;
                     }
                  }
                  mc2log << endl;
                  reply->setStatusCode( errorCode );
                  ok = false;
               } else { // Reply is ok
                  const TopRegionRequest* topRegReq = 
                     m_group->getTopRegionRequest( &*m_thread );

                  // Note that the topRegionID is a topRegionID - not CC.
                  if ( topRegionID == MAX_UINT32 ) {
                     // Find the topRegionMatch of type country.
                     const TopRegionMatch* topReg =
                        topRegReq->getCountryForMapID( crp->getMapID() );
                     if ( topReg != NULL ) {
                        topRegionID = topReg->getID();
                     }
                  }
               }
               delete navReq;
            } else if ( topRegionID != MAX_UINT32 && areaStr == NULL ) {
               // Have topregion and proximity search but no pos is ok now
            } else {
               mc2log << warn << "handleSearch: not valid pos";
               if ( topRegionID == MAX_UINT32 ) {
                  mc2log << " for unknown topRegionID ";
               }
               if ( areaStr == NULL ) {
                  mc2log << " for proximity ";
               }
               mc2log << endl;
               ok = false;
               reply->setStatusCode( 
                  NavReplyPacket::NAV_STATUS_MISSING_PARAMETER );
               reply->setStatusMessage( "Search Position" );
            }
         } // End if needs to lookup pos


         if ( ok ) {
            if ( areaStr != NULL ) {
               // Check if topRegionID is in allowed regions
               if ( m_thread->checkUserRegionAccess( topRegionID, user,
                                                     urmask ) )
               {
                  sr = new SearchRequest( 
                     reqID, searchParams, topRegionID, areaStr,
                     searchString.c_str(), m_thread->getTopRegionRequest(),
                     searchPos, &areaSearchParams );
               } else {
                  mc2log << warn << "handleSearch: selected topRegionID "
                         << hex << topRegionID << dec << " not allowed."
                         << endl;
                  ok = false;
                  reply->setStatusCode( 
                     NavReplyPacket::NAV_STATUS_OUTSIDE_ALLOWED_AREA );
               }
            } else { // Search around position
               // Will search the whole country.
               if ( searchPos.isValid() ) {
                  sr = new ClosestSearchRequest( 
                     reqID, searchParams, searchPos, searchString,
                     m_thread->getTopRegionRequest(),
                     allowedMaps ? *allowedMaps : set<uint32>() );
               } else if ( topRegionID != MAX_UINT32 ) {
                  if ( m_thread->checkUserRegionAccess( topRegionID, 
                                                        user, urmask ) )
                  {
                     sr = new ClosestSearchRequest( 
                        reqID, searchParams, topRegionID, searchString,
                        m_thread->getTopRegionRequest(),
                        allowedMaps ? *allowedMaps : set<uint32>() );
                  } else {
                     mc2log << warn << "handleSearch: proximity: selected "
                            << "topRegionID " << hex << topRegionID << dec
                            << " not allowed." << endl;
                     ok = false;
                     reply->setStatusCode( 
                        NavReplyPacket::NAV_STATUS_OUTSIDE_ALLOWED_AREA );
                  }
               } else {
                  mc2log << warn << "handleSearch: not valid pos nor "
                         << "topRegion ";
                  mc2log << endl;
                  ok = false;
                  reply->setStatusCode( 
                     NavReplyPacket::NAV_STATUS_MISSING_PARAMETER );
                  reply->setStatusMessage( 
                     "Search Position or TopRegion" );
               }
               searchForArea = false;
            }
         }
         
      } // End else if have selected search area
      
      if ( ok ) {
         m_thread->putRequest( sr );

         // Check sr
         mc2log << info << "handleSearch: Reply:";
         if ( sr->getStatus() != StringTable::OK ) {
            if ( sr->getStatus() == StringTable::TIMEOUT_ERROR ) {
               mc2log << " REQUEST_TIMEOUT";
               reply->setStatusCode( 
                  NavReplyPacket::NAV_STATUS_REQUEST_TIMEOUT );
            } else if ( sr->getStatus() == 
                        StringTable::OUTSIDE_ALLOWED_AREA )
            {
               mc2log << " OUTSIDE_ALLOWED_AREA";
               reply->setStatusCode( 
                  NavReplyPacket::NAV_STATUS_OUTSIDE_ALLOWED_AREA );
            } else { 
               mc2log << " NOT_OK";
               reply->setStatusCode( NavReplyPacket::NAV_STATUS_NOT_OK );
            }
         } else {
            // Add the result
            addMatches( rparams, sr, searchForArea, maxNbrMatches, 
                        areaStartIndex, itemStartIndex, 1302, 
                        1303, 1300, 1304, 1301 );
         } // End else sr is ok
         mc2log << endl;
         
         PacketContainer* searchAnswer = sr->getAnswer();
         
         // Debit search
         MC2String extraInfo = m_userHelp->makeExtraUserInfoStr( params );
         if ( !m_thread->getDebitHandler()->makeSearchDebit( 
                 userItem, sr, searchAnswer, areaStr,
                 searchString.c_str(), extraInfo.c_str() ) )
         {
            mc2log << warn << "handleSearch: debit failed." << endl;
         }


         delete searchAnswer;
         delete sr->getAnswer();
         delete sr;
      } // End if ok
   } // End if ok


   delete allowedMaps;
   delete selectedArea;

   return ok;
}
Beispiel #9
0
extern int main(int argc, char *argv[])
{
  unsigned i;
  Addr base, limit;
  mps_arena_t mpsArena;
  Arena arena; /* the ANSI arena which we use to allocate the BT */
  CBSStruct cbsStruct;
  CBS cbs;
  void *p;
  Addr dummyBlock;
  BT allocTable;
  Size size;
  Bool high;
  CBSFindDelete findDelete = CBSFindDeleteNONE;

  randomize(argc, argv);

  NAllocateTried = NAllocateSucceeded = NDeallocateTried =
    NDeallocateSucceeded = NNewBlocks = NDeleteBlocks =
    NGrowBlocks = NShrinkBlocks = 0;

  clearExpectations();

  die(mps_arena_create(&mpsArena, mps_arena_class_vm(), testArenaSIZE),
      "mps_arena_create");
  arena = (Arena)mpsArena; /* avoid pun */

  die((mps_res_t)BTCreate(&allocTable, arena, ArraySize),
      "failed to create alloc table");

  die((mps_res_t)CBSInit(arena, &cbsStruct, NULL, &cbsNewCallback,
                         &cbsDeleteCallback, &cbsGrowCallback,
                         &cbsShrinkCallback, MinSize,
                         Alignment, TRUE, TRUE),
      "failed to initialise CBS");
  cbs = &cbsStruct;

  BTSetRange(allocTable, 0, ArraySize); /* Initially all allocated */

  /* We're not going to use this block, but I feel unhappy just */
  /* inventing addresses. */
  die((mps_res_t)ControlAlloc(&p, arena, ArraySize * Alignment,
                              /* withReservoirPermit */ FALSE),
      "failed to allocate block");
  dummyBlock = (Addr)p; /* avoid pun */

  printf("Allocated block [%p, %p)\n", (void*)dummyBlock,
         (char *)dummyBlock + ArraySize);

  checkCBS(cbs, allocTable, dummyBlock);
  for(i = 0; i < NOperations; i++) {
    switch(cbsRnd(3)) {
    case 0: {
      randomRange(&base, &limit, allocTable, dummyBlock);
      allocate(cbs, dummyBlock, allocTable, base, limit);
    } break;
    case 1: {
      randomRange(&base, &limit, allocTable, dummyBlock);
      deallocate(cbs, dummyBlock, allocTable, base, limit);
    } break;
    case 2: {
      size = cbsRnd(ArraySize / 10) + 1;
      high = cbsRnd(2) ? TRUE : FALSE;
      switch(cbsRnd(6)) {
      case 0:
      case 1:
      case 2: findDelete = CBSFindDeleteNONE; break;
      case 3: findDelete = CBSFindDeleteLOW; break;
      case 4: findDelete = CBSFindDeleteHIGH; break;
      case 5: findDelete = CBSFindDeleteENTIRE; break;
      }
      find(cbs, dummyBlock, allocTable, size, high, findDelete);
    } break;
    }
    if (i % 5000 == 0)
      checkCBS(cbs, allocTable, dummyBlock);
  }

  checkExpectations();

  /* CBSDescribe prints a very long line. */
  /* CBSDescribe(cbs, mps_lib_get_stdout()); */

  printf("\nNumber of allocations attempted: %ld\n", NAllocateTried);
  printf("Number of allocations succeeded: %ld\n", NAllocateSucceeded);
  printf("Number of deallocations attempted: %ld\n", NDeallocateTried);
  printf("Number of deallocations succeeded: %ld\n", NDeallocateSucceeded);
  printf("Number of new large blocks: %ld\n", NNewBlocks);
  printf("Number of deleted large blocks: %ld\n", NDeleteBlocks);
  printf("Number of grown large blocks: %ld\n", NGrowBlocks);
  printf("Number of shrunk large blocks: %ld\n", NShrinkBlocks);
  printf("\nNo problems detected.\n");
  return 0;
}
Beispiel #10
0
static void find(CBS cbs, void *block, BT alloc, Size size, Bool high,
                 CBSFindDelete findDelete)
{
  Bool expected, found;
  Index expectedBase, expectedLimit;
  Addr foundBase, foundLimit, remainderBase, remainderLimit;
  Size oldSize, newSize;

  checkExpectations();

  expected = (high ? BTFindLongResRangeHigh : BTFindLongResRange)
               (&expectedBase, &expectedLimit, alloc,
                (Index)0, (Index)ArraySize, (Count)size);

  if (expected) {
    oldSize = (expectedLimit - expectedBase) * Alignment;
    remainderBase = addrOfIndex(block, expectedBase);
    remainderLimit = addrOfIndex(block, expectedLimit);

    switch(findDelete) {
    case CBSFindDeleteNONE: {
      /* do nothing */
    } break;
    case CBSFindDeleteENTIRE: {
      remainderBase = remainderLimit;
    } break;
    case CBSFindDeleteLOW: {
      expectedLimit = expectedBase + size;
      remainderBase = addrOfIndex(block, expectedLimit);
    } break;
    case CBSFindDeleteHIGH: {
      expectedBase = expectedLimit - size;
      remainderLimit = addrOfIndex(block, expectedBase);
    } break;
    }

    if (findDelete != CBSFindDeleteNONE) {
      newSize = AddrOffset(remainderBase, remainderLimit);

      if (oldSize >= MinSize) {
        if (newSize == 0)
          expectCallback(&CallbackDelete, oldSize, (Addr)0, (Addr)0);
        else if (newSize < MinSize)
          expectCallback(&CallbackDelete, oldSize,
                         remainderBase, remainderLimit);
        else
          expectCallback(&CallbackShrink, oldSize,
                         remainderBase, remainderLimit);
      }
    }
  }

  found = (high ? CBSFindLast : CBSFindFirst)
    (&foundBase, &foundLimit, cbs, size * Alignment, findDelete);

  Insist(found == expected);

  if (found) {
    Insist(expectedBase == indexOfAddr(block, foundBase));
    Insist(expectedLimit == indexOfAddr(block, foundLimit));
    checkExpectations();

    if (findDelete != CBSFindDeleteNONE)
      BTSetRange(alloc, expectedBase, expectedLimit);
  }

  return;
}
Beispiel #11
0
static void deallocate(CBS cbs, Addr block, BT allocTable,
                       Addr base, Addr limit)
{
  Res res;
  Index ib, il;
  Bool isAllocated;
  Addr outerBase = base, outerLimit = limit; /* interval containing [ib, il) */
  Addr freeBase, freeLimit;                  /* interval returned by CBS */

  ib = indexOfAddr(block, base);
  il = indexOfAddr(block, limit);

  isAllocated = BTIsSetRange(allocTable, ib, il);

  /*
  printf("deallocate: [%p, %p) -- %s\n",
         base, limit, isAllocated ? "succeed" : "fail");
  */

  NDeallocateTried++;

  if (isAllocated) {
    Size left, right, total;       /* Sizes of block and two fragments */

    /* Find the free blocks adjacent to the allocated block */
    if (ib > 0 && !BTGet(allocTable, ib - 1)) {
      outerBase =
        addrOfIndex(block, lastEdge(allocTable, ArraySize, ib - 1));
    } else {
      outerBase = base;
     }

    if (il < ArraySize && !BTGet(allocTable, il)) {
      outerLimit =
        addrOfIndex(block, nextEdge(allocTable, ArraySize, il));
    } else {
      outerLimit = limit;
    }

    left = AddrOffset(outerBase, base);
    right = AddrOffset(limit, outerLimit);
    total = AddrOffset(outerBase, outerLimit);

    /* based on detailed knowledge of CBS behaviour */
    checkExpectations();
    if (total >= MinSize && left < MinSize && right < MinSize) {
      if (left >= right)
        expectCallback(&CallbackNew, left, outerBase, outerLimit);
      else
        expectCallback(&CallbackNew, right, outerBase, outerLimit);
    } else if (left >= MinSize && right >= MinSize) {
      if (left >= right) {
        expectCallback(&CallbackDelete, right, (Addr)0, (Addr)0);
        expectCallback(&CallbackGrow, left, outerBase, outerLimit);
      } else {
        expectCallback(&CallbackDelete, left, (Addr)0, (Addr)0);
        expectCallback(&CallbackGrow, right, outerBase, outerLimit);
      }
    } else if (total >= MinSize) {
      if (left >= right) {
        Insist(left >= MinSize);
        Insist(right < MinSize);
        expectCallback(&CallbackGrow, left, outerBase, outerLimit);
      } else {
        Insist(left < MinSize);
        Insist(right >= MinSize);
        expectCallback(&CallbackGrow, right, outerBase, outerLimit);
      }
    }
  }

  res = CBSInsertReturningRange(&freeBase, &freeLimit, cbs, base, limit);

  if (!isAllocated) {
    die_expect((mps_res_t)res, MPS_RES_FAIL,
               "succeeded in inserting non-allocated block");
  } else { /* isAllocated */
    die_expect((mps_res_t)res, MPS_RES_OK,
               "failed to insert allocated block");

    NDeallocateSucceeded++;
    BTResRange(allocTable, ib, il);
    checkExpectations();
    Insist(freeBase == outerBase);
    Insist(freeLimit == outerLimit);
  }
}
Beispiel #12
0
static void allocate(CBS cbs, Addr block, BT allocTable,
                     Addr base, Addr limit)
{
  Res res;
  Index ib, il;                  /* Indexed for base and limit */
  Bool isFree;

  ib = indexOfAddr(block, base);
  il = indexOfAddr(block, limit);

  isFree = BTIsResRange(allocTable, ib, il);
 
  /*
  printf("allocate: [%p, %p) -- %s\n",
         base, limit, isFree ? "succeed" : "fail");
  */

  NAllocateTried++;

  if (isFree) {
    Addr outerBase, outerLimit;    /* interval containing [ib, il) */
    Size left, right, total;       /* Sizes of block and two fragments */

    outerBase =
      addrOfIndex(block, lastEdge(allocTable, ArraySize, ib));
    outerLimit =
      addrOfIndex(block, nextEdge(allocTable, ArraySize, il - 1));

    left = AddrOffset(outerBase, base);
    right = AddrOffset(limit, outerLimit);
    total = AddrOffset(outerBase, outerLimit);

    /* based on detailed knowledge of CBS behaviour */
    checkExpectations();
    if (total >= MinSize && left < MinSize && right < MinSize) {
      if (left == (Size)0 && right == (Size)0) {
        expectCallback(&CallbackDelete, total, (Addr)0, (Addr)0);
      } else if (left >= right) {
        expectCallback(&CallbackDelete, total, outerBase, base);
      } else {
        expectCallback(&CallbackDelete, total, limit, outerLimit);
      }
    } else if (left >= MinSize && right >= MinSize) {
      if (left >= right) {
        expectCallback(&CallbackShrink, total, outerBase, base);
        expectCallback(&CallbackNew, (Size)0, limit, outerLimit);
      } else {
        expectCallback(&CallbackNew, (Size)0, outerBase, base);
        expectCallback(&CallbackShrink, total, limit, outerLimit);
      }
    } else if (total >= MinSize) {
      if (left >= right) {
        Insist(left >= MinSize);
        Insist(right < MinSize);
        expectCallback(&CallbackShrink, total, outerBase, base);
      } else {
        Insist(left < MinSize);
        Insist(right >= MinSize);
        expectCallback(&CallbackShrink, total, limit, outerLimit);
      }
    }
  }

  res = CBSDelete(cbs, base, limit);

  if (!isFree) {
    die_expect((mps_res_t)res, MPS_RES_FAIL,
               "Succeeded in deleting allocated block");
  } else { /* isFree */
    die_expect((mps_res_t)res, MPS_RES_OK,
               "failed to delete free block");
    NAllocateSucceeded++;
    BTSetRange(allocTable, ib, il);
    checkExpectations();
  }
}