Example #1
0
static TIMER_CALLBACK( timer_tick )
{
	pockstat_state *state = machine.driver_data<pockstat_state>();
	ps_intc_set_interrupt_line(machine, param == 2 ? PS_INT_TIMER2 : (param == 1 ? PS_INT_TIMER1 : PS_INT_TIMER0), 1);
	//printf( "Timer %d is calling back\n", param );
	state->m_timer_regs.timer[param].count = state->m_timer_regs.timer[param].period;
	ps_timer_start(machine, param);
}
Example #2
0
static WRITE32_HANDLER( ps_timer_w )
{
	pockstat_state *state = space->machine().driver_data<pockstat_state>();
	switch(offset)
	{
		case 0x0000/4:
		case 0x0010/4:
		case 0x0020/4:
			verboselog(space->machine(), 0, "ps_timer_w: Timer %d Period = %08x & %08x\n", offset / (0x10/4), data, mem_mask );
			COMBINE_DATA(&state->m_timer_regs.timer[offset / (0x10/4)].period);
			break;
		case 0x0004/4:
		case 0x0014/4:
		case 0x0024/4:
			verboselog(space->machine(), 0, "ps_timer_w: Timer %d Count = %08x & %08x\n", offset / (0x10/4), data, mem_mask );
			COMBINE_DATA(&state->m_timer_regs.timer[offset / (0x10/4)].count);
			break;
		case 0x0008/4:
		case 0x0018/4:
		case 0x0028/4:
			verboselog(space->machine(), 0, "ps_timer_w: Timer %d Control = %08x & %08x\n", offset / (0x10/4), data, mem_mask );
			COMBINE_DATA(&state->m_timer_regs.timer[offset / (0x10/4)].control);
			if(state->m_timer_regs.timer[offset / (0x10/4)].control & 4)
			{
				ps_timer_start(space->machine(), offset / (0x10/4));
			}
			else
			{
				state->m_timer_regs.timer[offset / (0x10/4)].timer->adjust(attotime::never, offset / (0x10/4));
			}
			break;
		default:
			verboselog(space->machine(), 0, "ps_timer_w: Unknown Register %08x = %08x & %08x\n", 0x0a800000 + (offset << 2), data, mem_mask );
			break;
	}
}
Example #3
0
void mip_outmsg_send_rrq
(
  mip_session_info_type *  session
)
{
  nv_stat_enum_type  nv_status;            /* return val for ps_nv_read    */
  mip_rrq_msg        rrq;                  /* registration request message */
  byte *             ext;                  /* extension pointer            */
  uint32             spi;                  /* temporary var for SPI        */
  byte *             mn_ha_ss  = NULL;     /* MN-HA shared secret ptr      */
  byte *             mn_aaa_ss = NULL ;    /* MN-AAA shared secret ptr     */
  uint32             len;                  /* length to hash for MN-HA     */
  uint16             t_uint16;             /* temporary uint16             */
  boolean            result;               /* result of mipio_write()      */
  byte               mn_ha_ss_len;         /* MN-HA shared secret length   */
  byte               mn_aaa_ss_len;        /* MN-AAA shared secret length  */
#ifdef FEATURE_DS_MOBILE_IP_DMU
  byte               dmu_ix;               /* index for dmu_info           */
#ifdef FEATURE_DS_MOBILE_IP_DMU_DEBUG_CLEARTEXT
#error code not present
#endif /* FEATURE_DS_MOBILE_IP_DMU_DEBUG_CLEARTEXT */
#endif /* FEATURE_DS_MOBILE_IP_DMU */
  mip_event_payload_type  mip_event_payload;
  ps_timer_error_type     timer_result;
/*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -*/

  MSG_HIGH ("** Compose RRQ for session %d (info @ %x)", 
            MIP_SES_PTR_2_INDEX(session), 
            &rrq, 
            0);

  /*-------------------------------------------------------------------------
    Check to see if one second has passed since last RRQ.  If not, skip RRQ.
  -------------------------------------------------------------------------*/
  if (session->rsm_info.one_second_since_last_rrq == FALSE)
  {
    MSG_MED ("RRQ was sent less than a second ago, dump this one", 0,0,0);
    return;
  };

  /*-------------------------------------------------------------------------
    Check to see if foreign agent address is known.  If not, skip RRQ.
  -------------------------------------------------------------------------*/
  if (ma_info.ma_addr == 0)
  {
    MSG_MED ("We don't know FA addr, skipping RRQ", 0,0,0);
    return;
  }

  /*-------------------------------------------------------------------------
    Build the registration request body
  -------------------------------------------------------------------------*/
  rrq.type      = MIP_MSGTYPE_RRQ;
  rrq.flags     = 0;

  /*-------------------------------------------------------------------------
    Set reverse tunneling bit in RRQ as provisioned on the mobile.

    Note that this is an intolerant setting (me MUST reverse tunnel or we
    MUST NOT reverse tunnel, for mn_request_rev_tun = 1, 0 respectively).
  -------------------------------------------------------------------------*/
  if (session->mn_request_rev_tun)
  {
    rrq.flags |= MIP_RRQ_FLAG_REV_TUN;

    /*-----------------------------------------------------------------------
      To think about:
      If the mobile requires reverse tunneling but reverse tunneling is 
      not supported by one of the mobility agents, we could fail the call 
      here rather than waste time trying to register.  But this will require
      retooling of the state machines.
    -----------------------------------------------------------------------*/
  }

  rrq.lifetime  = dss_htons(ma_info.ma_lifetime);
 
  /*-------------------------------------------------------------------------
    Check to be sure that the home address has been provisioned, or if not
    that an NAI is present to identify the mobile.  If not, we can't
    register, so cause an error!
  -------------------------------------------------------------------------*/
  if ((session->home_addr == INADDR_ANY) && (session->nai_len == 0))
  {
    MSG_ERROR ("NAI not specified!  Home addr must be provisioned.",0,0,0);
    return;
  }

  /*-------------------------------------------------------------------------
    IP addresses are stored in network order, so no translation is required
    here. 
  -------------------------------------------------------------------------*/
  rrq.home_addr = session->home_addr;
  rrq.ha_addr   = session->ha_addrs[session->curr_ha_index];
  rrq.coa       = ma_info.ma_addr;

  /*-------------------------------------------------------------------------
    Read the time offset from NV and save it in the session info block.
  -------------------------------------------------------------------------*/
  ps_nv_item.ds_mip_mn_ha_time_delta.index = session->profile_index;
  nv_status = psi_get_nv_item(NV_DS_MIP_MN_HA_TIME_DELTA_I, &ps_nv_item);

  /*-------------------------------------------------------------------------
    If profile hasn't been written to NV yet, set time offset to zero. 
  -------------------------------------------------------------------------*/
  if (nv_status != NV_DONE_S)
  {
    MSG_HIGH ("time_offset for profile %d never written",
              session->profile_index, 0, 0);
    ps_nv_item.ds_mip_mn_ha_time_delta.time_delta = 0;
  }

  session->time_offset = ps_nv_item.ds_mip_mn_ha_time_delta.time_delta;

  /*-------------------------------------------------------------------------
    Get the NTP timestamp.  Note that the following assumes big-endian 
    architecture.  Add the HA/MN timebase offset correction to the id.
  -------------------------------------------------------------------------*/
  ds_get_ntp (&rrq.id1, &rrq.id2); 

  rrq.id1 += session->time_offset;
  MSG_HIGH ("registration ID is %x.%x (offset %x)",
            rrq.id1, rrq.id2, (session->time_offset));

  /*-------------------------------------------------------------------------
    Save the ID so we can match RRP to this RRQ
  -------------------------------------------------------------------------*/
  session->reg_id_msw = rrq.id1;
  session->reg_id_lsw = rrq.id2;

  /*-------------------------------------------------------------------------
    Convert the RRQ ID to network byte order
  -------------------------------------------------------------------------*/
  rrq.id1 = dss_htonl(rrq.id1);
  rrq.id2 = dss_htonl(rrq.id2);

  /*-------------------------------------------------------------------------
    Build the MN Network access identifier extension
  -------------------------------------------------------------------------*/
  ext = (byte *) &rrq.extensions;

  if (session->nai_len != 0)
  {
    MSG_LOW ("copying nai (%d bytes)",session->nai_len,0,0);

    BP_PUT8(ext, MIP_EXTTYPE_MN_NAI);
    BP_COPY8(ext, &session->nai_len);
    memcpy(ext, session->nai, session->nai_len);
    ext += session->nai_len; 
  }

#ifdef FEATURE_UIM_SUPPORT_3GPD
  if(UIM_3GPD_MIP_NV_SIP_NV == uim_3gpd_support() ||
     UIM_3GPD_MIP_NV_SIP_RUIM == uim_3gpd_support())
#endif /* FEATURE_UIM_SUPPORT_3GPD */
  {

  /*-------------------------------------------------------------------------
    Retrieve shared secret data. 

    If using RUIM, SS data is maintained on the card, and cannot
    be retrieved.  Hashing using SS data is done by the card

    Note: for now, it's ok to use ps_nv_item for temporary storage since we 
          are the only caller of psi_get_nv_item - this will need to be 
          fixed if anyone else calls this function.

    JD - consider, for security purposes, splitting the following function 
    into two functions - "get SS pointers" and "retrieve SS" so a malicious 
    user cannot call this any time to retrieve SS info
  -------------------------------------------------------------------------*/
  mip_auth_retrieve_ss_data( session,
                             &mn_ha_ss, 
                             &mn_ha_ss_len, 
                             &mn_aaa_ss, 
                             &mn_aaa_ss_len );

  }

  /*-------------------------------------------------------------------------
    Build the MN-HA Authentication extension
    
    If no MN-HA shared secret is provided, the extension is still included,
    the authenticator calculated as if the shared secret was of length 0.
  -------------------------------------------------------------------------*/
  MSG_LOW ("Building MN-HA Authentiation",0,0,0);

  BP_PUT8(ext, MIP_EXTTYPE_AUTH_MN_HA);
  BP_PUT8(ext, 4 + MIP_AUTH_MD5_LEN);
  
  /*-------------------------------------------------------------------------
    Note: RFC2002 authenticator calculation *DOES NOT* include SPI
  -------------------------------------------------------------------------*/
  len = (ext - (byte *) &rrq); 

  /*-------------------------------------------------------------------------
    Set MN-HA SPI to provisioned value. 
  -------------------------------------------------------------------------*/

  /*-------------------------------------------------------------------------
    Later, implement an SPI lookup according to authentication algorithm, 
    i.e. something like:

    spi = mip_auth_lookup_spi (mn_ha_auth_lookup, 
                               calc_auth_md5_prefix_plus_suffix);
  -------------------------------------------------------------------------*/
  spi = session->mn_ha_spi;
  spi = dss_htonl(spi);
  BP_COPY32 (ext, (byte *) &spi);               /* TYPE CASTING ESSENTIAL! */
  
  MSG_LOW ("calculating MD5 authenticator",0,0,0);
  
  /*-------------------------------------------------------------------------
    Check to see if RFC 2002bis style authentication is enabled -
    authenticator calculation *DOES* include SPI
  -------------------------------------------------------------------------*/
  if (ds_atcop_qcmipt_val & MIP_QCMIPT_MN_HA_AUTH_2002BIS_BIT)
  {
    len += sizeof(uint32);               /* rfc2002 doesn't hash SPI value */
  }


  mip_auth_calc_md5_prefix_plus_suffix( &rrq, 
                                        len, 
                                        (void *) mn_ha_ss, 
                                        mn_ha_ss_len,
                                        ext,
                                        session->profile_index );
  ext += MIP_AUTH_MD5_LEN;

  /*-------------------------------------------------------------------------
    If the foreign agent issued a challenge in the agent advertisement,
    include the MN-FA challenge extension in the registration request.
  -------------------------------------------------------------------------*/
  if (ma_info.challenge_length)
  {
    /*-----------------------------------------------------------------------
      Build the mn-fa challenge extension
    -----------------------------------------------------------------------*/
    BP_PUT8(ext, MIP_EXTTYPE_MN_FA_CHAL);
    BP_COPY8(ext, &ma_info.challenge_length);
    memcpy( ext, 
            ma_info.fa_challenge,
            ma_info.challenge_length );
    ext += ma_info.challenge_length;
  }

  /*-------------------------------------------------------------------------
    If the foreign agent sent a challenge, or Dynamic Mobile Update is 
    in progress, the mobile must also provide the AAA authentication 
    extension so the AAA can authenticate the mobile.  
  -------------------------------------------------------------------------*/
 
  if (ma_info.challenge_length 
#ifdef FEATURE_DS_MOBILE_IP_DMU
      || session->dmu == TRUE
#endif /* FEATURE_DS_MOBILE_IP_DMU */
     )
  {

#ifdef FEATURE_DS_MOBILE_IP_DMU
    /*-----------------------------------------------------------------------
      If DMU in progress, build the DMU_Key_Data extension
    -----------------------------------------------------------------------*/
    if (session->dmu == TRUE)
    {
      dmu_ix = MIP_SES_PTR_2_INDEX (session);
      if(!mip_dmu_info[dmu_ix].encrypted)
      {
        /*-------------------------------------------------------------------
          AAA wants a DMU, but we haven't finished encrypting the keys yet.

          So just drop this RRQ for now, hopefully by the time the re-rrq 
          timer expires, we will have finished encryption.

          JD - better, post an event to reduce the rrq_cnt by one for this
               case.
        -------------------------------------------------------------------*/
        MSG_MED("Encryption not yet complete, skip RRQ",0,0,0);
        return;
      }

      MSG_MED ("Adding MIP_KEY_DATA extn",0,0,0);
      
#ifdef FEATURE_DS_MOBILE_IP_DMU_DEBUG
#error code not present
#endif /* FEATURE_DS_MOBILE_IP_DMU_DEBUG */

      /*---------------------------------------------------------------------
        make critical vendor specific extension header first:
        - length is 138 = 6 (header) + 128 (encrypted keys) + 4 (PKI)
      ---------------------------------------------------------------------*/
      BP_PUT8(ext, MIP_EXTTYPE_CVSE);
      BP_PUT8(ext, 0);

      BP_PUT16(ext, 138);  
      BP_PUT32(ext, ((uint32) MIP_CVSE_VERIZON_ORG_ID & 0x00FFFFFF));
      BP_PUT16(ext, MIP_DMU_CVSETYPE_DMU_KEY_DATA);

#ifdef FEATURE_DS_MOBILE_IP_DMU_DEBUG_CLEARTEXT
#error code not present
#else /* encrypted DMU payload */

      /*---------------------------------------------------------------------
        Build encrypted key data VSE. 
      ---------------------------------------------------------------------*/
        memcpy (ext, 
                mip_dmu_info[dmu_ix].encrypted_key_data,
                MIP_DMU_ENCRYPTED_KEY_DATA_LEN);
        ext += MIP_DMU_ENCRYPTED_KEY_DATA_LEN;

      /*---------------------------------------------------------------------
        Clear the mn auth from memory for security reasons
      ---------------------------------------------------------------------*/
        memset (mip_dmu_info[dmu_ix].key_data.mn_auth,
                0,
                MIP_DMU_MN_AUTH_LEN);
#endif /* !FEATURE_DS_MOBILE_IP_DMU_DEBUG_CLEARTEXT */
      
      /*---------------------------------------------------------------------
        make Public Key Identifier
        - currently, only support PK_EXPANSION 0xFF = default (no extension)
        - currently, only support AV 1 = RSA-1024
        - currently, only support DMUV 0 = DMU v1.3
      ---------------------------------------------------------------------*/
      BP_COPY8(ext, &mip_dmu_info[dmu_ix].pk_info.pkoid);
      BP_COPY8(ext, &mip_dmu_info[dmu_ix].pk_info.pkoi);
      BP_PUT8(ext, MIP_DMU_PK_VERSION);

#ifdef FEATURE_DS_MOBILE_IP_DMU_DEBUG_CLEARTEXT
#error code not present
#else /* encrypted mode */
      /*---------------------------------------------------------------------
        Insert DMU version 1.3
      ---------------------------------------------------------------------*/
        BP_PUT8(ext, MIP_DMU_AV << 4 | MIP_DMU_DMUV);
#endif /* FEATURE_DS_MOBILE_IP_DMU_DEBUG_CLEARTEXT */
    }
#endif /* FEATURE_DS_MOBILE_IP_DMU */

    /*-----------------------------------------------------------------------
      Build the MN-AAA authentication extension. 

      Note AUTH_CHAP_LEN and calc_auth_chap() are hard coded and not
      configurable.
    -----------------------------------------------------------------------*/
    BP_PUT8(ext, MIP_EXTTYPE_AUTH_GEN);
    BP_PUT8(ext, MIP_GEN_EXT_SUBTYPE_AAA_AUTH);
    t_uint16 = 4 + MIP_AUTH_MD5_LEN;
    t_uint16 = dss_htons (t_uint16);
    BP_COPY16(ext, (byte *) &t_uint16);         /* TYPE CASTING ESSENTIAL! */

    /*-----------------------------------------------------------------------
      should look like:
      spi = mip_auth_lookup_spi( mn_aaa_auth_lookup, calc_auth_chap );
    -----------------------------------------------------------------------*/
    spi = session->mn_aaa_spi;
    spi = dss_htonl(spi);
    BP_COPY32 (ext, (byte *) &spi);             /* TYPE CASTING ESSENTIAL! */

    /*-----------------------------------------------------------------------
      If the foreign agent sent a challenge, the mobile must also provide
      the AAA authentication extension so the FA can authenticate the 
      mobile.  So build the MN-AAA authentication extension. 

      Reuse 'spi' as return value from calc_auth_chap()
    -----------------------------------------------------------------------*/
    spi = mip_auth_calc_chap( 
            &rrq, 
            ext - (byte *) &rrq,
            (void *) mn_aaa_ss,
            mn_aaa_ss_len,
            ma_info.fa_challenge,
            ma_info.challenge_length,
            ext,
            session->profile_index );
    ext += spi;
  }

  /*-------------------------------------------------------------------------
    Send the RRQ message to the foreign agent
  -------------------------------------------------------------------------*/
  MSG_LOW ("Sending RRQ to %x:%d",
            dss_htonl(ma_info.ma_addr), MIP_UDP_PORTNO, 0);
  result = mipio_write( MIP_SES_PTR_2_INDEX(session),
                        &rrq, 
                        ext - (byte *) &rrq,
                        ma_info.ma_addr,
                        MIP_UDP_PORTNO ); 
  /*-----------------------------------------------------------------------
     Report RRQ sent event
  -----------------------------------------------------------------------*/
  mip_event_payload.mip_event = event_mip_rrq_sent;

  if (result == TRUE) {
     mip_event_payload.info = MIP_EVENT_INFO_SENT_OTA; 
  }
  else{
     mip_event_payload.info = MIP_EVENT_INFO_SENT_FAIL; 
  }

  event_report_payload(EVENT_MIP, 
                       sizeof (mip_event_payload), 
                       &mip_event_payload);

  if (result == TRUE)
  {
    MSG_HIGH ("RRQ Sent",0,0,0);

    /*-----------------------------------------------------------------------
      Set the holdoff timer to make sure RRQ's are sent no less than 1s apart
    -----------------------------------------------------------------------*/
    timer_result = ps_timer_start (session->rsm_info.rrq_holdoff_timer, 1000);
    ASSERT (timer_result != PS_TIMER_FAILURE);

    /*-----------------------------------------------------------------------
      Clear the holdoff flag to suppress RRQ's for a second.

      Do it after setting the timer.  There is no race condition 
      because:
      i)  the following line should take less than 1 second to execute.
      ii) for the case where the timer is active and the corresponding RRP 
          is received before this timeout occurs, resetting the timer above
          will ensure that the callback isn't called, putting the holdoff
          variable TRUE incorrectly.
    -----------------------------------------------------------------------*/
    session->rsm_info.one_second_since_last_rrq = FALSE;
     
    MSG_MED ("Set session %d RRQ holdoff timer for 1s", 
             MIP_SES_PTR_2_INDEX(session), 0, 0);
  }
  else
  {
    MSG_HIGH ("RRQ send failed",0,0,0);
  }

} /* mip_outmsg_send_rrq() */