Пример #1
0
 def GetSubscriberData(self, request, context):
     """
     Return the subscription data for the subscriber
     """
     print_grpc(
         request, self._print_grpc_payload,
         "Get Subscriber Data Request:",
     )
     sid = SIDUtils.to_str(request)
     try:
         response = self._store.get_subscriber_data(sid)
         # get_sub_profile converts the imsi id to a string prependend with IMSI string,
         # so strip the IMSI prefix in sid
         imsi = sid[4:]
         sub_profile = self._lte_processor.get_sub_profile(imsi)
         response.non_3gpp.ambr.max_bandwidth_ul = sub_profile.max_ul_bit_rate
         response.non_3gpp.ambr.max_bandwidth_dl = sub_profile.max_dl_bit_rate
         response.non_3gpp.ambr.br_unit = apn_pb2.AggregatedMaximumBitrate.BitrateUnitsAMBR.BPS
     except SubscriberNotFoundError:
         context.set_details("Subscriber not found: %s" % sid)
         context.set_code(grpc.StatusCode.NOT_FOUND)
         response = subscriberdb_pb2.SubscriberData()
     print_grpc(
         response, self._print_grpc_payload,
         "Get Subscriber Data Response:",
     )
     return response
Пример #2
0
    def DeleteSuciProfile(self, request, context):
        """
        DeleteSuciProfile - Deletes suciprofile from the store      # noqa: D403

        Args:
            request: SuciProfile
            context: context

        Returns: None

        Raises:
            RpcError: Key is invalid

        """
        print_grpc(
            request, self._print_grpc_payload,
            "Delete SuciProfile Request:",
        )

        if request.home_net_public_key_id not in self.suciprofile_db_dict.keys():
            logging.warning(
                "The home_net_public_key_id:%d is not a valid key,"
                "try again", request.home_net_public_key_id,
            )
            context.set_details("Suciprofile not found")
            context.set_code(grpc.StatusCode.NOT_FOUND)
            raise grpc.RpcError("Key is invalid")
        else:
            del self.suciprofile_db_dict[request.home_net_public_key_id]
Пример #3
0
    def AddSuciProfile(self, request, context):
        """
        AddSuciProfile - Adds a suciprofile to the store        # noqa: D403

        Args:
            request: SuciProfile
            context: context

        Returns: None

        Raises:
            RpcError: Key already exists
        """
        print_grpc(
            request, self._print_grpc_payload,
            "Add SuciProfile Request:",
        )

        if request.home_net_public_key_id in self.suciprofile_db_dict.keys():
            logging.warning(
                "home_net_public_key_id:%d already exist",
                request.home_net_public_key_id,
            )
            context.set_details("Duplicate suciprofile")
            context.set_code(grpc.StatusCode.ALREADY_EXISTS)
            raise grpc.RpcError("Key already exists")

        self.suciprofile_db_dict[request.home_net_public_key_id] = suci_profile_data(
            request.protection_scheme, request.home_net_public_key,
            request.home_net_private_key,
        )
Пример #4
0
    def ListSuciProfile(self, request, context):
        """
        ListSuciProfile - Returns SuciProfile list      # noqa: D403

        Args:
            request: SuciProfile
            context: context

        Returns:
            response: SuciProfileList
        """
        print_grpc(
            request, self._print_grpc_payload,
            "List Suciprofile Request:",
        )
        suciprofiles = []
        for k, v in self.suciprofile_db_dict.items():
            suciprofiles.append(
                subscriberdb_pb2.SuciProfile(
                    home_net_public_key_id=int(k),
                    protection_scheme=v.protection_scheme,
                    home_net_public_key=v.home_network_public_key,
                    home_net_private_key=v.home_network_private_key,
                ),
            )

        response = subscriberdb_pb2.SuciProfileList(suci_profiles=suciprofiles)
        print_grpc(
            response, self._print_grpc_payload,
            "List SuciProfile Response:",
        )
        return response
Пример #5
0
 def GetAllEnodebStatus(self, _=None, context=None) -> AllEnodebStatus:
     print_grpc(
         Void(),
         self._print_grpc_payload,
         "GetAllEnodebStatus Request:",
     )
     all_enb_status = AllEnodebStatus()
     serial_list = self.state_machine_manager.get_connected_serial_id_list()
     for enb_serial in serial_list:
         enb_status = get_single_enb_status(
             enb_serial,
             self.state_machine_manager,
         )
         all_enb_status.enb_status_list.add(
             device_serial=enb_status.device_serial,
             ip_address=enb_status.ip_address,
             connected=enb_status.connected,
             configured=enb_status.configured,
             opstate_enabled=enb_status.opstate_enabled,
             rf_tx_on=enb_status.rf_tx_on,
             rf_tx_desired=enb_status.rf_tx_desired,
             gps_connected=enb_status.gps_connected,
             ptp_connected=enb_status.ptp_connected,
             mme_connected=enb_status.mme_connected,
             gps_longitude=enb_status.gps_longitude,
             gps_latitude=enb_status.gps_latitude,
             fsm_state=enb_status.fsm_state,
         )
     print_grpc(
         all_enb_status,
         self._print_grpc_payload,
         "GetAllEnodebStatus Response:",
     )
     return all_enb_status
Пример #6
0
    async def _send_to_state_service(self, request: DeleteStatesRequest):
        state_client = self._grpc_client_manager.get_client()
        try:
            print_grpc(
                request, self._print_grpc_payload,
                "Garbage collector sending to state service",
            )
            response = await grpc_async_wrapper(
                state_client.DeleteStates.future(
                    request,
                    DEFAULT_GRPC_TIMEOUT,
                ),
            )
            print_grpc(response, self._print_grpc_payload)

        except grpc.RpcError as err:
            logging.error(
                "GRPC call failed for state deletion: %s",
                err,
                extra=EXCLUDE_FROM_ERROR_MONITORING if indicates_connection_error(err) else None,
            )
        else:
            for redis_dict in self._redis_dicts:
                for key in redis_dict.garbage_keys():
                    await self._delete_state_from_redis(redis_dict, key)
Пример #7
0
def get_all_enb_state(
        print_grpc_payload: bool = False) -> Optional[Dict[int, int]]:
    """
    Make RPC call to 'GetENBState' method of s1ap service
    """
    try:
        chan = ServiceRegistry.get_rpc_channel(
            S1AP_SERVICE_NAME,
            ServiceRegistry.LOCAL,
        )
    except ValueError:
        logger.error('Cant get RPC channel to %s', S1AP_SERVICE_NAME)
        return {}
    client = S1apServiceStub(chan)
    try:
        request = Void()
        print_grpc(
            request,
            print_grpc_payload,
            "Get All eNB State Request:",
        )
        res = client.GetENBState(request, DEFAULT_GRPC_TIMEOUT)
        print_grpc(
            res,
            print_grpc_payload,
            "Get All eNB State Response:",
        )
        return res.enb_state_map
    except grpc.RpcError as err:
        logger.warning(
            "GetEnbState error: [%s] %s",
            err.code(),
            err.details(),
        )
    return {}
Пример #8
0
 def Reboot(self, request: EnodebIdentity, context=None) -> None:
     """ Reboot eNodeB """
     print_grpc(
         request,
         self._print_grpc_payload,
         "Reboot Request:",
     )
     handler = self._get_handler(request.device_serial)
     handler.reboot_asap()
Пример #9
0
    def M5GAuthenticationInformation(self, request, context):
        print_grpc(
            request,
            self._print_grpc_payload,
            "M5GAuthenticationInformation Request:",
        )
        imsi = request.user_name
        aia = subscriberauth_pb2.M5GAuthenticationInformationAnswer()

        try:
            re_sync_info = request.resync_info
            # resync_info =
            #  rand + auts, rand is of 16 bytes + auts is of 14 bytes
            sizeof_resync_info = 30
            if re_sync_info and (re_sync_info != b'\x00' * sizeof_resync_info):
                rand = re_sync_info[:16]
                auts = re_sync_info[16:]
                self.lte_processor.resync_lte_auth_seq(imsi, rand, auts)

            m5g_ran_auth_vectors = \
                self.lte_processor.generate_m5g_auth_vector(
                    imsi,
                    request.serving_network_name.encode(
                        'utf-8',
                    ),
                )

            metrics.M5G_AUTH_SUCCESS_TOTAL.inc()

            # Generate and return response message
            aia.error_code = subscriberauth_pb2.SUCCESS
            m5gauth_vector = aia.m5gauth_vectors.add()
            m5gauth_vector.rand = bytes(m5g_ran_auth_vectors.rand)
            m5gauth_vector.xres_star = m5g_ran_auth_vectors.xres_star[16:]
            m5gauth_vector.autn = m5g_ran_auth_vectors.autn
            m5gauth_vector.kseaf = m5g_ran_auth_vectors.kseaf
            return aia

        except CryptoError as e:
            logging.error("Auth error for %s: %s", imsi, e)
            metrics.M5G_AUTH_FAILURE_TOTAL.labels(
                code=metrics.DIAMETER_AUTHENTICATION_REJECTED, ).inc()
            aia.error_code = metrics.DIAMETER_AUTHENTICATION_REJECTED
            return aia

        except SubscriberNotFoundError as e:
            logging.warning("Subscriber not found: %s", e)
            metrics.M5G_AUTH_FAILURE_TOTAL.labels(
                code=metrics.DIAMETER_ERROR_USER_UNKNOWN, ).inc()
            aia.error_code = metrics.DIAMETER_ERROR_USER_UNKNOWN
            return aia
        finally:
            print_grpc(
                aia,
                self._print_grpc_payload,
                "M5GAuthenticationInformation Response:",
            )
Пример #10
0
 def PurgeUE(self, request, context):
     logging.warning(
         "Purge request not implemented: %s %s",
         request.DESCRIPTOR.full_name,
         MessageToJson(request),
     )
     pur = s6a_proxy_pb2.PurgeUEAnswer()
     print_grpc(pur, self._print_grpc_payload, "PUR:")
     return pur
Пример #11
0
 def RebootAll(self, _=None, context=None) -> None:
     """ Reboot all connected eNodeB devices """
     print_grpc(
         Void(),
         self._print_grpc_payload,
         "RebootAll Request:",
     )
     serial_list = self.state_machine_manager.get_connected_serial_id_list()
     for enb_serial in serial_list:
         handler = self._get_handler(enb_serial)
         handler.reboot_asap()
Пример #12
0
 def DeleteSubscriber(self, request, context):
     """
     Delete a subscriber from the store
     """
     print_grpc(
         request, self._print_grpc_payload,
         "Delete Subscriber Request:",
     )
     sid = SIDUtils.to_str(request)
     logging.debug("Delete subscriber rpc for sid: %s", sid)
     self._store.delete_subscriber(sid)
Пример #13
0
    async def _send_to_state_service(self, request: ReportStatesRequest):
        state_client = self._grpc_client_manager.get_client()
        try:
            print_grpc(
                request,
                self._print_grpc_payload,
                "Sending to state service",
            )
            response = await grpc_async_wrapper(
                state_client.ReportStates.future(
                    request,
                    DEFAULT_GRPC_TIMEOUT,
                ),
                self._loop,
            )
            print_grpc(response, self._print_grpc_payload)

        except grpc.RpcError as err:
            logging.error(
                "GRPC call failed for state replication: %s",
                err,
                extra=EXCLUDE_FROM_ERROR_MONITORING
                if indicates_connection_error(err) else None,
            )
        else:
            unreplicated_states = set()
            for idAndError in response.unreportedStates:
                logging.warning(
                    "Failed to replicate state for (%s,%s): %s",
                    idAndError.type,
                    idAndError.deviceID,
                    idAndError.error,
                )
                unreplicated_states.add((idAndError.type, idAndError.deviceID))
            # Update in-memory map for successfully reported states
            for state in request.states:
                if (state.type, state.deviceID) in unreplicated_states:
                    continue
                in_mem_key = make_mem_key(state.deviceID, state.type)
                self._state_versions[in_mem_key] = state.version

                logging.debug(
                    "Successfully replicated state for: "
                    "deviceID: %s,"
                    "type: %s, "
                    "version: %d",
                    state.deviceID,
                    state.type,
                    state.version,
                )
        finally:
            # reset timeout to config-specified + some buffer
            self.set_timeout(self._interval * 2)
Пример #14
0
    def AuthenticationInformation(self, request, context):
        print_grpc(request, self._print_grpc_payload, "AIR:")
        imsi = request.user_name
        aia = s6a_proxy_pb2.AuthenticationInformationAnswer()
        try:
            plmn = request.visited_plmn

            re_sync_info = request.resync_info
            # resync_info =
            #  rand + auts, rand is of 16 bytes + auts is of 14 bytes
            sizeof_resync_info = 30
            if re_sync_info and (re_sync_info != b'\x00' * sizeof_resync_info):
                rand = re_sync_info[:16]
                auts = re_sync_info[16:]
                self.lte_processor.resync_lte_auth_seq(imsi, rand, auts)

            rand, xres, autn, kasme = \
                self.lte_processor.generate_lte_auth_vector(imsi, plmn)

            metrics.S6A_AUTH_SUCCESS_TOTAL.inc()

            # Generate and return response message
            aia.error_code = s6a_proxy_pb2.SUCCESS
            eutran_vector = aia.eutran_vectors.add()
            eutran_vector.rand = bytes(rand)
            eutran_vector.xres = xres
            eutran_vector.autn = autn
            eutran_vector.kasme = kasme
            logging.info("Auth success: %s", imsi)
            return aia

        except CryptoError as e:
            logging.error("Auth error for %s: %s", imsi, e)
            metrics.S6A_AUTH_FAILURE_TOTAL.labels(
                code=metrics.DIAMETER_AUTHENTICATION_REJECTED, ).inc()
            aia.error_code = metrics.DIAMETER_AUTHENTICATION_REJECTED
            return aia

        except SubscriberNotFoundError as e:
            logging.warning("Subscriber not found: %s", e)
            metrics.S6A_AUTH_FAILURE_TOTAL.labels(
                code=metrics.DIAMETER_ERROR_USER_UNKNOWN, ).inc()
            aia.error_code = metrics.DIAMETER_ERROR_USER_UNKNOWN
            return aia
        except ServiceNotActive as e:
            logging.error("Service not active for %s: %s", imsi, e)
            metrics.M5G_AUTH_FAILURE_TOTAL.labels(
                code=metrics.DIAMETER_ERROR_UNAUTHORIZED_SERVICE, ).inc()
            aia.error_code = metrics.DIAMETER_ERROR_UNAUTHORIZED_SERVICE
            return aia
        finally:
            print_grpc(aia, self._print_grpc_payload, "AIA:")
Пример #15
0
 def AddSubscriber(self, request, context):
     """
     Adds a subscriber to the store
     """
     print_grpc(request, self._print_grpc_payload,
                "Add Subscriber Request:")
     sid = SIDUtils.to_str(request.sid)
     logging.debug("Add subscriber rpc for sid: %s", sid)
     try:
         self._store.add_subscriber(request)
     except DuplicateSubscriberError:
         context.set_details("Duplicate subscriber: %s" % sid)
         context.set_code(grpc.StatusCode.ALREADY_EXISTS)
Пример #16
0
    def M5GDecryptImsiSUCIRegistration(self, request, context):
        """
        M5GDecryptImsiSUCIRegistration
        """
        print_grpc(
            request,
            self._print_grpc_payload,
            "M5GDecryptImsiSUCIRegistration Request:",
        )
        aia = subscriberdb_pb2.M5GSUCIRegistrationAnswer()

        try:
            suciprofile = self.suciprofile_db.get(request.ue_pubkey_identifier)
            if suciprofile is None:
                set_grpc_err(
                    context,
                    StatusCode.NOT_FOUND,
                    f"identifier {request.ue_pubkey_identifier} not found",
                )
                return aia

            if suciprofile.protection_scheme == 0:
                profile = 'A'
            elif suciprofile.protection_scheme == 1:
                profile = 'B'

            home_network_info = ECIES_HN(
                suciprofile.home_net_private_key,
                profile,
            )

            msin_recv = home_network_info.unprotect(
                request.ue_pubkey,
                request.ue_ciphertext,
                request.ue_encrypted_mac,
            )

            aia.ue_msin_recv = msin_recv[:10]
            logging.info("Deconcealed IMSI: %s", aia.ue_msin_recv)
            return aia

        except SuciProfileNotFoundError as e:
            logging.warning("Suciprofile not found: %s", e)
            return aia

        finally:
            print_grpc(
                aia,
                self._print_grpc_payload,
                "M5GDecryptImsiSUCIRegistration Response:",
            )
Пример #17
0
    async def _resync(self):
        states_to_sync = []
        for redis_dict in self._redis_dicts:
            for key in redis_dict:
                version = redis_dict.get_version(key)
                device_id = make_scoped_device_id(key, redis_dict.state_scope)
                state_id = StateID(
                    type=redis_dict.redis_type,
                    deviceID=device_id,
                )
                id_and_version = IDAndVersion(id=state_id, version=version)
                states_to_sync.append(id_and_version)

        if len(states_to_sync) == 0:
            logging.debug("Not re-syncing state. No local state found.")
            return
        state_client = self._grpc_client_manager.get_client()
        request = SyncStatesRequest(states=states_to_sync)
        print_grpc(
            request,
            self._print_grpc_payload,
            "Sending resync state request",
        )
        response = await grpc_async_wrapper(
            state_client.SyncStates.future(
                request,
                DEFAULT_GRPC_TIMEOUT,
            ),
            self._loop,
        )
        print_grpc(
            response,
            self._print_grpc_payload,
            "Received resync state request",
        )
        unsynced_states = set()
        for id_and_version in response.unsyncedStates:
            unsynced_states.add((
                id_and_version.id.type,
                id_and_version.id.deviceID,
            ))
        # Update in-memory map to add already synced states
        for state in request.states:
            in_mem_key = make_mem_key(state.id.deviceID, state.id.type)
            if (state.id.type, state.id.deviceID) not in unsynced_states:
                self._state_versions[in_mem_key] = state.version

        self._has_resync_completed = True
        logging.info("Successfully resynced state with Orchestrator!")
Пример #18
0
 def ListSubscribers(self, request, context):  # pylint:disable=unused-argument
     """
     Return a list of subscribers from the store
     """
     print_grpc(
         request, self._print_grpc_payload,
         "List Subscribers Request:",
     )
     sids = self._store.list_subscribers()
     sid_msgs = [SIDUtils.to_pb(sid) for sid in sids]
     response = subscriberdb_pb2.SubscriberIDSet(sids=sid_msgs)
     print_grpc(
         response, self._print_grpc_payload,
         "List Subscribers Response:",
     )
     return response
Пример #19
0
 def UpdateSubscriber(self, request, context):
     """
     Update the subscription data
     """
     try:
         print_grpc(
             request, self._print_grpc_payload,
             "Update Subscriber Request",
         )
     except Exception as e:  # pylint: disable=broad-except
         logging.debug("Exception while trying to log GRPC: %s", e)
     sid = SIDUtils.to_str(request.data.sid)
     try:
         with self._store.edit_subscriber(sid) as subs:
             request.mask.MergeMessage(
                 request.data, subs, replace_message_field=True,
             )
     except SubscriberNotFoundError:
         context.set_details("Subscriber not found: %s" % sid)
         context.set_code(grpc.StatusCode.NOT_FOUND)
Пример #20
0
 def GetStatus(self, _=None, context=None) -> ServiceStatus:
     """
     Get eNodeB status
     Note: input variable defaults used so this can be either called locally
     or as an RPC.
     """
     print_grpc(
         Void(),
         self._print_grpc_payload,
         "GetStatus Request:",
     )
     status = dict(get_service_status(self.state_machine_manager))
     status_message = ServiceStatus()
     status_message.meta.update(status)
     print_grpc(
         status_message,
         self._print_grpc_payload,
         "GetStatus Response:",
     )
     return status_message
Пример #21
0
 def GetEnodebStatus(
     self,
     request: EnodebIdentity,
     _context=None,
 ) -> SingleEnodebStatus:
     print_grpc(
         request,
         self._print_grpc_payload,
         "GetEnodebStatus Request:",
     )
     response = get_single_enb_status(
         request.device_serial,
         self.state_machine_manager,
     )
     print_grpc(
         response,
         self._print_grpc_payload,
         "GetEnodebStatus Response:",
     )
     return response
Пример #22
0
 def GetSubscriberData(self, request, context):
     """
     Return the subscription data for the subscriber
     """
     print_grpc(
         request,
         self._print_grpc_payload,
         "Get Subscriber Data Request:",
     )
     sid = SIDUtils.to_str(request)
     try:
         response = self._store.get_subscriber_data(sid)
     except SubscriberNotFoundError:
         context.set_details("Subscriber not found: %s" % sid)
         context.set_code(grpc.StatusCode.NOT_FOUND)
         response = subscriberdb_pb2.SubscriberData()
     print_grpc(
         response,
         self._print_grpc_payload,
         "Get Subscriber Data Response:",
     )
     return response
Пример #23
0
    def UpdateLocation(self, request, context):
        print_grpc(request, self._print_grpc_payload, "ULR:")
        imsi = request.user_name
        ula = s6a_proxy_pb2.UpdateLocationAnswer()
        try:
            profile = self.lte_processor.get_sub_profile(imsi)
        except SubscriberNotFoundError as e:
            ula.error_code = s6a_proxy_pb2.USER_UNKNOWN
            logging.warning('Subscriber not found for ULR: %s', e)
            print_grpc(ula, self._print_grpc_payload, "ULA:")
            return ula

        try:
            sub_data = self.lte_processor.get_sub_data(imsi)
        except SubscriberNotFoundError as e:
            ula.error_code = s6a_proxy_pb2.USER_UNKNOWN
            logging.warning("Subscriber not found for ULR: %s", e)
            print_grpc(ula, self._print_grpc_payload, "ULA:")
            return ula
        ula.error_code = s6a_proxy_pb2.SUCCESS
        ula.default_context_id = 0
        ula.total_ambr.max_bandwidth_ul = profile.max_ul_bit_rate
        ula.total_ambr.max_bandwidth_dl = profile.max_dl_bit_rate
        ula.all_apns_included = 0
        ula.msisdn = self.encode_msisdn(sub_data.non_3gpp.msisdn)

        context_id = 0
        for apn in sub_data.non_3gpp.apn_config:
            sec_apn = ula.apn.add()
            sec_apn.context_id = context_id
            context_id += 1
            sec_apn.service_selection = apn.service_selection
            sec_apn.qos_profile.class_id = apn.qos_profile.class_id
            sec_apn.qos_profile.priority_level = apn.qos_profile.priority_level
            sec_apn.qos_profile.preemption_capability = (
                apn.qos_profile.preemption_capability)
            sec_apn.qos_profile.preemption_vulnerability = (
                apn.qos_profile.preemption_vulnerability)

            sec_apn.ambr.max_bandwidth_ul = apn.ambr.max_bandwidth_ul
            sec_apn.ambr.max_bandwidth_dl = apn.ambr.max_bandwidth_dl
            sec_apn.ambr.unit = (s6a_proxy_pb2.UpdateLocationAnswer.
                                 AggregatedMaximumBitrate.BitrateUnitsAMBR.BPS)
            sec_apn.pdn = (
                apn.pdn if apn.pdn else
                s6a_proxy_pb2.UpdateLocationAnswer.APNConfiguration.IPV4)

        print_grpc(ula, self._print_grpc_payload, "ULA:")
        return ula
Пример #24
0
    def GetParameter(
        self,
        request: GetParameterRequest,
        context: Any,
    ) -> GetParameterResponse:
        """
        Sends a GetParameterValues message. Used for testing only.

        Different data models will have different names for the same
        parameter. Whatever name that the data model uses, we call the
        'parameter path', eg. "Device.DeviceInfo.X_BAICELLS_COM_GPS_Status"
        We denote 'ParameterName' to be a standard string name for
        equivalent parameters between different data models
        """
        print_grpc(
            request,
            self._print_grpc_payload,
            "GetParameter Request:",
        )
        # Get the parameter value information
        parameter_path = request.parameter_name
        handler = self._get_handler(request.device_serial)
        data_model = handler.data_model
        param_name = data_model.get_parameter_name_from_path(parameter_path)
        param_value = str(handler.get_parameter(param_name))

        # And now construct the response to the rpc request
        get_parameter_values_response = GetParameterResponse()
        get_parameter_values_response.parameters.add(
            name=parameter_path,
            value=param_value,
        )
        print_grpc(
            get_parameter_values_response,
            self._print_grpc_payload,
            "GetParameter Response:",
        )
        return get_parameter_values_response
Пример #25
0
    def SetParameter(self, request: SetParameterRequest, context: Any) -> None:
        """
        Sends a SetParameterValues message. Used for testing only.

        Different data models will have different names for the same
        parameter. Whatever name that the data model uses, we call the
        'parameter path', eg. "Device.DeviceInfo.X_BAICELLS_COM_GPS_Status"
        We denote 'ParameterName' to be a standard string name for
        equivalent parameters between different data models
        """
        print_grpc(
            request,
            self._print_grpc_payload,
            "SetParameter Request:",
        )
        # Parse the request
        if request.HasField('value_int'):
            value = (request.value_int, 'int')
        elif request.HasField('value_bool'):
            value = (request.value_bool, 'boolean')
        elif request.HasField('value_string'):
            value = (request.value_string, 'string')
        else:
            context.set_details(
                'SetParameter: Unsupported type %d',
                request.type,
            )
            context.set_code(grpc.StatusCode.INVALID_ARGUMENT)
            return

        # Update the handler so it will set the parameter value
        parameter_path = request.parameter_name
        handler = self._get_handler(request.device_serial)
        data_model = handler.data_model
        param_name = data_model.get_parameter_name_from_path(parameter_path)
        handler.set_parameter_asap(param_name, value)