// Copyright (c) 2017-2023, Mudita Sp. z.o.o. All rights reserved. // For licensing, see https://github.com/mudita/MuditaOS/LICENSE.md #include #include #include #include #include #include #include #include #include #include #include #include #include #include using namespace cellular; using namespace app::manager::actions; TEST_CASE("Emergency handling") { struct EmergencyTest { // the request came as emergency request bool isEmergencyRequest; // mock that the the number is sim requiring emergency number bool isNumberEmergencySim; // mock that the the number is no sim emergency number bool isNumberEmergencyNoSim; // mock that sim is inserted bool insertSim; // mock that phone is connected to network bool isConnectedToNetwork; // reject reason if applicable std::optional rejectReason; // expected typeid name of created request std::string expectedType; // expected command crated by factory std::string expectedCommand = "ATD600700800;"; // test number std::string number = "600700800"; }; std::vector testCases = { ////// normal request // no SIM and SIM emergency number / sim inserted {false, true, true, true, true, std::nullopt, typeid(CallRequest).name()}, // no SIM and SIM emergency number / sim inserted / no network connection {true, true, true, true, false, std::nullopt, typeid(CallRequest).name()}, // no SIM emergency number / sim inserted {false, false, true, true, true, std::nullopt, typeid(CallRequest).name()}, // SIM emergency number / sim inserted {false, true, false, true, true, std::nullopt, typeid(CallRequest).name()}, // no SIM and SIM emergency number / no sim inserted {false, true, true, false, true, std::nullopt, typeid(CallRequest).name()}, // no SIM emergency number / no sim inserted {false, false, true, false, true, std::nullopt, typeid(CallRequest).name()}, // SIM emergency number / no sim inserted {false, true, false, false, true, RejectRequest::RejectReason::NoSim, typeid(RejectRequest).name(), ""}, // normal number / sim inserted {false, false, false, true, true, std::nullopt, typeid(CallRequest).name()}, // normal number / no sim inserted {false, false, false, false, true, RejectRequest::RejectReason::NoSim, typeid(RejectRequest).name(), ""}, ////// emergency request // no SIM and SIM emergency number / sim inserted {true, true, true, true, true, std::nullopt, typeid(CallRequest).name()}, // no SIM emergency number / sim inserted {true, false, true, true, true, std::nullopt, typeid(CallRequest).name()}, // SIM emergency number / sim inserted {true, true, false, true, true, std::nullopt, typeid(CallRequest).name()}, // no SIM and SIM emergency number / no sim inserted {true, true, true, false, true, std::nullopt, typeid(CallRequest).name()}, // no SIM emergency number / no sim inserted {true, false, true, false, true, std::nullopt, typeid(CallRequest).name()}, // SIM emergency number / no sim inserted {true, true, false, false, true, RejectRequest::RejectReason::NoSim, typeid(RejectRequest).name(), ""}, // normal number / sim inserted {true, false, false, true, true, RejectRequest::RejectReason::NotAnEmergencyNumber, typeid(RejectRequest).name(), ""}, // normal number / no sim inserted {true, false, false, false, true, RejectRequest::RejectReason::NotAnEmergencyNumber, typeid(RejectRequest).name(), ""}, }; int idx = 0; for (auto &test : testCases) { if (test.insertSim) { Store::GSM::get()->sim = Store::GSM::SIM::SIM1; } else { Store::GSM::get()->sim = Store::GSM::SIM::NONE; } std::vector channelMockResponse; if (test.isNumberEmergencyNoSim) { channelMockResponse.emplace_back("+QECCNUM: 0,\"" + test.number + "\""); } if (test.isNumberEmergencySim) { channelMockResponse.emplace_back("+QECCNUM: 1,\"" + test.number + "\""); } if (test.isConnectedToNetwork) { channelMockResponse.emplace_back("+COPS: 0,0,\"PLAY\",7"); } auto dummyChannel = at::GenericChannel(at::Result::Code::OK, channelMockResponse); RequestFactory requestFactory(test.number, dummyChannel, test.isEmergencyRequest ? cellular::api::CallMode::Emergency : cellular::api::CallMode::Regular, test.insertSim); std::shared_ptr request = requestFactory.create(); INFO("Failed test case idx: " + std::to_string(idx)); REQUIRE(request != nullptr); REQUIRE(typeid(*request.get()).name() == test.expectedType); if (test.expectedType == typeid(RejectRequest).name()) { auto rejectRequest = std::static_pointer_cast(request); REQUIRE(test.rejectReason == rejectRequest->getRejectReason()); } if (request) { auto requestCommand = request->command(); REQUIRE(requestCommand.getCmd() == test.expectedCommand); } idx++; } } TEST_CASE("MMI requests") { Store::GSM::get()->sim = Store::GSM::SIM::SIM1; struct TestCase { const std::string requestString; const std::string expectedCommandString; const std::type_info &expectedType; const bool expectedValid = true; }; std::vector testCases = { /// USSD {R"(*100*#)", R"(AT+CUSD=1,*100*#,15)", typeid(UssdRequest)}, /// ImeiRequest {R"(*#06#)", R"(AT+GSN)", typeid(ImeiRequest)}, /// ClipRequest // bad procedure type {R"(*30#)", std::string(), typeid(ClipRequest), false}, // query {R"(*#30#)", R"(AT+CLIP?)", typeid(ClipRequest)}, // bad procedure type {R"(##30#)", std::string(), typeid(ClipRequest), false}, // bad procedure type {R"(#30#)", std::string(), typeid(ClipRequest), false}, // bad procedure type {R"(**30#)", std::string(), typeid(ClipRequest), false}, // temporary mode enable {R"(*30#600700800)", std::string(), typeid(CallRequest)}, // temporary mode disable {R"(#30#600700800)", std::string(), typeid(CallRequest)}, /// ClirRequest // bad procedure type {R"(*31#)", R"(AT+CLIR=1)", typeid(ClirRequest)}, // query {R"(*#31#)", R"(AT+CLIR?)", typeid(ClirRequest)}, // bad procedure type {R"(##31#)", std::string(), typeid(ClirRequest), false}, // bad procedure type {R"(#31#)", R"(AT+CLIR=2)", typeid(ClirRequest)}, // bad procedure type {R"(**31#)", std::string(), typeid(ClirRequest), false}, /// ColpRequest // bad procedure type {R"(*76#)", R"(AT+COLP=1)", typeid(ColpRequest)}, // query {R"(*#76#)", R"(AT+COLP?)", typeid(ColpRequest)}, // bad procedure type {R"(##76#)", std::string(), typeid(ColpRequest), false}, // bad procedure type {R"(#76#)", R"(AT+COLP=0)", typeid(ColpRequest)}, // bad procedure type {R"(**76#)", std::string(), typeid(ColpRequest), false}, /// CallBarringRequest // BAOC (Bar All Outgoing Calls) {R"(*33#)", R"(AT+CLCK="AO",1)", typeid(CallBarringRequest)}, // lock {R"(*33*1111#)", R"(AT+CLCK="AO",1,"1111")", typeid(CallBarringRequest)}, // lock with pass {R"(*33*1111*10#)", R"(AT+CLCK="AO",1,"1111",13)", typeid(CallBarringRequest)}, // lock with pass and BS {R"(#33#)", R"(AT+CLCK="AO",0)", typeid(CallBarringRequest)}, // unlock {R"(#33*1111#)", R"(AT+CLCK="AO",0,"1111")", typeid(CallBarringRequest)}, // unlock with pass {R"(#33*1111*11#)", R"(AT+CLCK="AO",0,"1111",1)", typeid(CallBarringRequest)}, // unlock with pass and BS {R"(*#33#)", R"(AT+CLCK="AO",2)", typeid(CallBarringRequest)}, // query {R"(*#33*1111#)", R"(AT+CLCK="AO",2,"1111")", typeid(CallBarringRequest)}, // query with pass {R"(*#33*1111*12#)", R"(AT+CLCK="AO",2,"1111",12)", typeid(CallBarringRequest)}, // query with pass and BS {R"(**33#)", std::string(), typeid(CallBarringRequest), false}, // bad procedure - register {R"(##33#)", std::string(), typeid(CallBarringRequest), false}, // bad procedure - erasure {R"(*#33*1111*17#)", std::string(), typeid(CallBarringRequest), false}, // unsupported BS - Voice Group Call {R"(*#33*1111*18#)", std::string(), typeid(CallBarringRequest), false}, // unsupported BS - Voice Broadcast {R"(*#33*1111*99#)", std::string(), typeid(CallBarringRequest), false}, // unsupported BS - All GPRS bearer {R"(*#33*1111*45#)", std::string(), typeid(CallBarringRequest), false}, // unsupported BS - random /// BOIC (Bar Outgoing International Calls) {R"(*331#)", R"(AT+CLCK="OI",1)", typeid(CallBarringRequest)}, // lock {R"(*331*2222#)", R"(AT+CLCK="OI",1,"2222")", typeid(CallBarringRequest)}, // lock with pass {R"(*331*2222*13#)", R"(AT+CLCK="OI",1,"2222",4)", typeid(CallBarringRequest)}, // lock with pass and BS {R"(#331#)", R"(AT+CLCK="OI",0)", typeid(CallBarringRequest)}, // unlock {R"(#331*2222#)", R"(AT+CLCK="OI",0,"2222")", typeid(CallBarringRequest)}, // unlock with pass {R"(#331*2222*16#)", R"(AT+CLCK="OI",0,"2222",8)", typeid(CallBarringRequest)}, // unlock with pass and BS {R"(*#331#)", R"(AT+CLCK="OI",2)", typeid(CallBarringRequest)}, // query {R"(*#331*2222#)", R"(AT+CLCK="OI",2,"2222")", typeid(CallBarringRequest)}, // query with pass {R"(*#331*2222*19#)", R"(AT+CLCK="OI",2,"2222",5)", typeid(CallBarringRequest)}, // query with pass and BS {R"(**331#)", std::string(), typeid(CallBarringRequest), false}, // bad procedure - register {R"(##331#)", std::string(), typeid(CallBarringRequest), false}, // bad procedure - erasure /// BOIC-exHC (Bar Outgoing International Calls except to home country) {R"(*332#)", R"(AT+CLCK="OX",1)", typeid(CallBarringRequest)}, // lock {R"(*332*3333#)", R"(AT+CLCK="OX",1,"3333")", typeid(CallBarringRequest)}, // lock {R"(*332*2222*20#)", R"(AT+CLCK="OX",1,"2222",50)", typeid(CallBarringRequest)}, // lock with pass {R"(#332#)", R"(AT+CLCK="OX",0)", typeid(CallBarringRequest)}, // unlock with pass and BS {R"(#332*3333#)", R"(AT+CLCK="OX",0,"3333")", typeid(CallBarringRequest)}, // unlock {R"(#332*2222*21#)", R"(AT+CLCK="OX",0,"2222",32)", typeid(CallBarringRequest)}, // unlock with pass {R"(*#332#)", R"(AT+CLCK="OX",2)", typeid(CallBarringRequest)}, // query with pass and BS {R"(*#332*3333#)", R"(AT+CLCK="OX",2,"3333")", typeid(CallBarringRequest)}, // query with pass {R"(*#332*2222*22#)", R"(AT+CLCK="OX",2,"2222",16)", typeid(CallBarringRequest)}, // query with pass and BS {R"(**332#)", std::string(), typeid(CallBarringRequest), false}, // bad procedure - register {R"(##332#)", std::string(), typeid(CallBarringRequest), false}, // bad procedure - erasure /// BAIC (Bar All Incoming Calls) {R"(*35#)", R"(AT+CLCK="AI",1)", typeid(CallBarringRequest)}, // lock {R"(*35*1234#)", R"(AT+CLCK="AI",1,"1234")", typeid(CallBarringRequest)}, // lock with pass {R"(*35*2222*24#)", R"(AT+CLCK="AI",1,"2222",16)", typeid(CallBarringRequest)}, // lock with pass and BS {R"(#35#)", R"(AT+CLCK="AI",0)", typeid(CallBarringRequest)}, // unlock {R"(#35*1234#)", R"(AT+CLCK="AI",0,"1234")", typeid(CallBarringRequest)}, // unlock with pass {R"(#35*2222*25#)", R"(AT+CLCK="AI",0,"2222",32)", typeid(CallBarringRequest)}, // unlock with pass and BS {R"(*#35#)", R"(AT+CLCK="AI",2)", typeid(CallBarringRequest)}, // query {R"(*#35*1234#)", R"(AT+CLCK="AI",2,"1234")", typeid(CallBarringRequest)}, // query with pass {R"(*#35*2222*26#)", R"(AT+CLCK="AI",2,"2222",17)", typeid(CallBarringRequest)}, // query with pass and BS {R"(**35#)", std::string(), typeid(CallBarringRequest), false}, // bad procedure - register {R"(##35#)", std::string(), typeid(CallBarringRequest), false}, // bad procedure - erasure /// BIC-Roam (Bar Incoming Calls when Roaming outside the home country) {R"(*351#)", R"(AT+CLCK="IR",1)", typeid(CallBarringRequest)}, // lock {R"(*351*1234#)", R"(AT+CLCK="IR",1,"1234")", typeid(CallBarringRequest)}, // lock with pass {R"(*351*2222*10#)", R"(AT+CLCK="IR",1,"2222",13)", typeid(CallBarringRequest)}, // lock with pass and BS {R"(#351#)", R"(AT+CLCK="IR",0)", typeid(CallBarringRequest)}, // unlock {R"(#351*1234#)", R"(AT+CLCK="IR",0,"1234")", typeid(CallBarringRequest)}, // unlock with pass {R"(#351*2222*11#)", R"(AT+CLCK="IR",0,"2222",1)", typeid(CallBarringRequest)}, // unlock with pass and BS {R"(*#351#)", R"(AT+CLCK="IR",2)", typeid(CallBarringRequest)}, // query {R"(*#351*1234#)", R"(AT+CLCK="IR",2,"1234")", typeid(CallBarringRequest)}, // query with pass {R"(*#351*2222*12#)", R"(AT+CLCK="IR",2,"2222",12)", typeid(CallBarringRequest)}, // query with pass and BS {R"(**351#)", std::string(), typeid(CallBarringRequest), false}, // bad procedure - register {R"(##351#)", std::string(), typeid(CallBarringRequest), false}, // bad procedure - erasure /// All barring services {R"(*330#)", R"(AT+CLCK="AB",1)", typeid(CallBarringRequest)}, // lock {R"(*330*1234#)", R"(AT+CLCK="AB",1,"1234")", typeid(CallBarringRequest)}, // lock with pass {R"(*330*2222*13#)", R"(AT+CLCK="AB",1,"2222",4)", typeid(CallBarringRequest)}, // lock with pass and BS {R"(#330#)", R"(AT+CLCK="AB",0)", typeid(CallBarringRequest)}, // unlock {R"(#330*1234#)", R"(AT+CLCK="AB",0,"1234")", typeid(CallBarringRequest)}, // unlock with pass {R"(#330*2222*16#)", R"(AT+CLCK="AB",0,"2222",8)", typeid(CallBarringRequest)}, // unlock with pass and BS {R"(*#330#)", R"(AT+CLCK="AB",2)", typeid(CallBarringRequest)}, // query {R"(*#330*1234#)", R"(AT+CLCK="AB",2,"1234")", typeid(CallBarringRequest)}, // query with pass {R"(*#330*2222*19#)", R"(AT+CLCK="AB",2,"2222",5)", typeid(CallBarringRequest)}, // query with pass and BS {R"(**330#)", std::string(), typeid(CallBarringRequest), false}, // bad procedure - register {R"(##330#)", std::string(), typeid(CallBarringRequest), false}, // bad procedure - erasure /// All outgoing barring services {R"(*333#)", R"(AT+CLCK="AG",1)", typeid(CallBarringRequest)}, // lock {R"(*333*1234#)", R"(AT+CLCK="AG",1,"1234")", typeid(CallBarringRequest)}, // lock with pass {R"(*333*2222*20#)", R"(AT+CLCK="AG",1,"2222",50)", typeid(CallBarringRequest)}, // lock with pass and BS {R"(#333#)", R"(AT+CLCK="AG",0)", typeid(CallBarringRequest)}, // unlock {R"(#333*1234#)", R"(AT+CLCK="AG",0,"1234")", typeid(CallBarringRequest)}, // unlock with pass {R"(#333*2222*21#)", R"(AT+CLCK="AG",0,"2222",32)", typeid(CallBarringRequest)}, // unlock with pass and BS {R"(*#333#)", R"(AT+CLCK="AG",2)", typeid(CallBarringRequest)}, // query {R"(*#333*1234#)", R"(AT+CLCK="AG",2,"1234")", typeid(CallBarringRequest)}, // query with pass {R"(*#333*2222*22#)", R"(AT+CLCK="AG",2,"2222",16)", typeid(CallBarringRequest)}, // query with pass and BS {R"(**333#)", std::string(), typeid(CallBarringRequest), false}, // bad procedure - register {R"(##333#)", std::string(), typeid(CallBarringRequest), false}, // bad procedure - erasure /// All incoming barring services {R"(*353#)", R"(AT+CLCK="AC",1)", typeid(CallBarringRequest)}, // lock {R"(*353*1234#)", R"(AT+CLCK="AC",1,"1234")", typeid(CallBarringRequest)}, // lock with pass {R"(*353*2222*24#)", R"(AT+CLCK="AC",1,"2222",16)", typeid(CallBarringRequest)}, // lock with pass and BS {R"(#353#)", R"(AT+CLCK="AC",0)", typeid(CallBarringRequest)}, // unlock {R"(#353*1234#)", R"(AT+CLCK="AC",0,"1234")", typeid(CallBarringRequest)}, // unlock with pass {R"(#353*2222*25#)", R"(AT+CLCK="AC",0,"2222",32)", typeid(CallBarringRequest)}, // unlock with pass and BS {R"(*#353#)", R"(AT+CLCK="AC",2)", typeid(CallBarringRequest)}, // query {R"(*#353*1234#)", R"(AT+CLCK="AC",2,"1234")", typeid(CallBarringRequest)}, // query with pass {R"(*#353*2222*10#)", R"(AT+CLCK="AC",2,"2222",13)", typeid(CallBarringRequest)}, // query with pass and BS {R"(**353#)", std::string(), typeid(CallBarringRequest), false}, // bad procedure - register {R"(##353#)", std::string(), typeid(CallBarringRequest), false}, // bad procedure - erasure /// CallWaitingRequest // enable all {R"(*43#)", R"(AT+CCWA=1,1)", typeid(CallWaitingRequest)}, // enable all {R"(*43*#)", R"(AT+CCWA=1,1)", typeid(CallWaitingRequest)}, // enable all tele services {R"(*43*10#)", R"(AT+CCWA=1,1,13)", typeid(CallWaitingRequest)}, // enable voice {R"(*43*11#)", R"(AT+CCWA=1,1,1)", typeid(CallWaitingRequest)}, // enable data {R"(*43*12#)", R"(AT+CCWA=1,1,12)", typeid(CallWaitingRequest)}, // enable fax {R"(*43*13#)", R"(AT+CCWA=1,1,4)", typeid(CallWaitingRequest)}, // enable sms {R"(*43*16#)", R"(AT+CCWA=1,1,8)", typeid(CallWaitingRequest)}, // enable all tele except sms {R"(*43*19#)", R"(AT+CCWA=1,1,5)", typeid(CallWaitingRequest)}, // enable all bearer {R"(*43*20#)", R"(AT+CCWA=1,1,50)", typeid(CallWaitingRequest)}, // enable data circuit sync {R"(*43*24#)", R"(AT+CCWA=1,1,16)", typeid(CallWaitingRequest)}, // enable data circuit async {R"(*43*25#)", R"(AT+CCWA=1,1,32)", typeid(CallWaitingRequest)}, // disable all {R"(#43#)", R"(AT+CCWA=1,0)", typeid(CallWaitingRequest)}, // query all {R"(*#43#)", R"(AT+CCWA=1,2)", typeid(CallWaitingRequest)}, // bad procedure ** {R"(**43#)", std::string(), typeid(CallWaitingRequest), false}, // bad procedure ## {R"(##43#)", std::string(), typeid(CallWaitingRequest), false}, // bad service group {R"(*43*17#)", std::string(), typeid(CallWaitingRequest), false}, // bad service group {R"(*43*17#)", std::string(), typeid(CallWaitingRequest), false}, /// CallForwardingRequest // all diversions {R"(##002#)", R"(AT+CCFC=4,4)", typeid(CallForwardingRequest)}, // all conditional redirections {R"(**004*666555444#)", R"(AT+CCFC=5,3,"666555444")", typeid(CallForwardingRequest)}, {R"(##004#)", R"(AT+CCFC=5,4)", typeid(CallForwardingRequest)}, // unconditional divert {R"(**21*666555444#)", R"(AT+CCFC=0,3,"666555444")", typeid(CallForwardingRequest)}, {R"(*21#)", R"(AT+CCFC=0,1)", typeid(CallForwardingRequest)}, {R"(#21#)", R"(AT+CCFC=0,0)", typeid(CallForwardingRequest)}, {R"(##21#)", R"(AT+CCFC=0,4)", typeid(CallForwardingRequest)}, {R"(*#21#)", R"(AT+CCFC=0,2)", typeid(CallForwardingRequest)}, // divert when not answered {R"(**61*666555444#)", R"(AT+CCFC=2,3,"666555444")", typeid(CallForwardingRequest)}, {R"(*61#)", R"(AT+CCFC=2,1)", typeid(CallForwardingRequest)}, {R"(#61#)", R"(AT+CCFC=2,0)", typeid(CallForwardingRequest)}, {R"(##61#)", R"(AT+CCFC=2,4)", typeid(CallForwardingRequest)}, {R"(*#61#)", R"(AT+CCFC=2,2)", typeid(CallForwardingRequest)}, // divert when off or not {R"(**62*666555444#)", R"(AT+CCFC=3,3,"666555444")", typeid(CallForwardingRequest)}, {R"(*62#)", R"(AT+CCFC=3,1)", typeid(CallForwardingRequest)}, {R"(#62#)", R"(AT+CCFC=3,0)", typeid(CallForwardingRequest)}, {R"(##62#)", R"(AT+CCFC=3,4)", typeid(CallForwardingRequest)}, {R"(*#62#)", R"(AT+CCFC=3,2)", typeid(CallForwardingRequest)}, // divert when busy or pressing reject {R"(**67*666555444#)", R"(AT+CCFC=1,3,"666555444")", typeid(CallForwardingRequest)}, {R"(*67#)", R"(AT+CCFC=1,1)", typeid(CallForwardingRequest)}, {R"(#67#)", R"(AT+CCFC=1,0)", typeid(CallForwardingRequest)}, {R"(##67#)", R"(AT+CCFC=1,4)", typeid(CallForwardingRequest)}, {R"(*#67#)", R"(AT+CCFC=1,2)", typeid(CallForwardingRequest)}, // alternative register and on {R"(*21*666555444#)", R"(AT+CCFC=0,1,"666555444")", typeid(CallForwardingRequest)}, // optional parameters - basic service group {R"(*21*666555444*16#)", R"(AT+CCFC=0,1,"666555444",129,8)", typeid(CallForwardingRequest)}, {R"(*21*+48666555444*19#)", R"(AT+CCFC=0,1,"+48666555444",145,5)", typeid(CallForwardingRequest)}, // optional parameters - time {R"(*21*666555444*16*30#)", R"(AT+CCFC=0,1,"666555444",129,8,,,30)", typeid(CallForwardingRequest)}, {R"(*21*+48666555444*19*20#)", R"(AT+CCFC=0,1,"+48666555444",145,5,,,20)", typeid(CallForwardingRequest)}, // not valid - timeout exceeds maximum {R"(*21*+48666555444*19*40#)", std::string(), typeid(CallForwardingRequest), false}, /// PasswordRegistrationRequest // total incoming and outgoing service barring (empty string) {R"(**03**23*111*111#)", R"(AT+CPWD="AB","23","111")", typeid(PasswordRegistrationRequest)}, // outgoing call barring {R"(**03*33*1234*4321*4321#)", R"(AT+CPWD="AO","1234","4321")", typeid(PasswordRegistrationRequest)}, // outgoing international call barring {R"(**03*331*1234*4321*4321#)", R"(AT+CPWD="OI","1234","4321")", typeid(PasswordRegistrationRequest)}, // outgoing international call barring, excluding to home {R"(**03*332*1234*4321*4321#)", R"(AT+CPWD="OX","1234","4321")", typeid(PasswordRegistrationRequest)}, // incoming call barring {R"(**03*35*1234*4321*4321#)", R"(AT+CPWD="AI","1234","4321")", typeid(PasswordRegistrationRequest)}, // incoming call barring, when international roaming {R"(**03*351*1234*4321*4321#)", R"(AT+CPWD="IR","1234","4321")", typeid(PasswordRegistrationRequest)}, // total incoming and outgoing service barring {R"(**03*330*1234*4321*4321#)", R"(AT+CPWD="AB","1234","4321")", typeid(PasswordRegistrationRequest)}, // total outgoing service barring {R"(**03*333*1234*4321*4321#)", R"(AT+CPWD="AG","1234","4321")", typeid(PasswordRegistrationRequest)}, // total incoming service barring {R"(**03*353*1234*4321*4321#)", R"(AT+CPWD="AC","1234","4321")", typeid(PasswordRegistrationRequest)}, // alternative procedure type * {R"(*03*353*1234*4321*4321#)", R"(AT+CPWD="AC","1234","4321")", typeid(PasswordRegistrationRequest)}, // bad procedure type * fallback to UUSD {R"(*#03*353*1234*4321*4321#)", R"(AT+CUSD=1,*#03*353*1234*4321*4321#,15)", typeid(UssdRequest)}, // bad procedure type ## {R"(##03*353*1234*4321*4321#)", std::string(), typeid(UssdRequest)}, // bad procedure type # {R"(#03*353*1234*4321*4321#)", std::string(), typeid(UssdRequest)}, // no password {R"(**03*353***#)", std::string(), typeid(PasswordRegistrationRequest), false}, // no password {R"(**03*353*24**#)", std::string(), typeid(PasswordRegistrationRequest), false}, // no password {R"(**03*353**34*#)", std::string(), typeid(PasswordRegistrationRequest), false}, // no password {R"(**03*353***34#)", std::string(), typeid(PasswordRegistrationRequest), false}, // password does not match {R"(**03*353*56*46*74#)", std::string(), typeid(PasswordRegistrationRequest), false}, /// PinChangeRequest // Change PIN {R"(**04*0000*1111*1111#)", R"(AT+CPWD="SC","0000","1111")", typeid(PinChangeRequest)}, // Change PIN2 {R"(**042*0000*1111*1111#)", R"(AT+CPWD="P2","0000","1111")", typeid(PinChangeRequest)}, // Change PIN by PUK {R"(**05*0000*1111*1111#)", R"(AT+CPIN="0000","1111")", typeid(PinChangeRequest)}, // Change PIN by PUK more than 4 {R"(**042*00002*11113*11113#)", R"(AT+CPWD="P2","00002","11113")", typeid(PinChangeRequest)}, // bad procedure type * {R"(*042*00002*11112*11112#)", std::string(), typeid(UssdRequest)}, // bad procedure type ## {R"(##042*00002*11112*11112#)", std::string(), typeid(UssdRequest)}, // bad procedure type # {R"(#042*00002*11112*11112#)", std::string(), typeid(UssdRequest)}, // bad procedure type *# {R"(*#042*00002*11112*11112#)", std::string(), typeid(UssdRequest)}, // no password {R"(**042*00002**#)", std::string(), typeid(PinChangeRequest), false}, // no password {R"(**042***11112#)", std::string(), typeid(PinChangeRequest), false}, // no password {R"(**042**11112*#)", std::string(), typeid(PinChangeRequest), false}, // no password {R"(**042**11112*#)", std::string(), typeid(PinChangeRequest), false}, // password does not match {R"(**042*0000*1111*2222#)", std::string(), typeid(PinChangeRequest), false}, /// call {R"(666555777)", std::string(), typeid(CallRequest)}, // {R"(+48666555777)", std::string(), typeid(CallRequest)}, }; for (auto &testCase : testCases) { std::vector channelMockResponse; // connected to network channelMockResponse.emplace_back("+COPS: 0,0,\"PLAY\",7"); auto mockChannel = at::GenericChannel(at::Result::Code::OK, channelMockResponse); RequestFactory requestFactory(testCase.requestString, mockChannel, cellular::api::CallMode::Regular, true); auto request = requestFactory.create(); auto requestCommand = request->command(); INFO("Failed on testcase: " << testCase.requestString); REQUIRE(typeid(*request.get()).name() == testCase.expectedType.name()); REQUIRE(request->isValid() == testCase.expectedValid); if (typeid(*request.get()).name() == typeid(CallRequest).name()) { REQUIRE(requestCommand.getCmd() == "ATD" + testCase.requestString + ";"); } else if (typeid(*request.get()).name() == typeid(UssdRequest).name()) { REQUIRE(requestCommand.getCmd() == "AT+CUSD=1," + testCase.requestString + ",15"); } else { if (requestCommand.getCmd() == testCase.expectedCommandString) { LOG_ERROR("HERE"); } REQUIRE(requestCommand.getCmd() == testCase.expectedCommandString); } } }