Ejemplo n.º 1
0
static void CommModuleSendRegistrationRequestToNetwork(C1222AL* p)
{
    Unsigned8 request[MAX_REGISTRATION_REQUEST]; 
    Unsigned16 index;
    Unsigned16 length;
    Unsigned8 epsemBuffer[100]; // need to fix this
    Epsem epsem;
    Unsigned8 relayAddressLength;
    Unsigned8* relayAddress;
    ACSE_Message* pMsg;
    C1222ApTitle apTitle;
    
    // <register>	::=	27H <node-type> <connection-type> <device-class>
	//	                    <ap-title> <serial-number> <address-length>
	//                  	<native-address> <registration-period>
	//
	// max size = 1 + 1 + 1 + 4
	//            + 20 + 20 + 1 + 20 + 3 = 71
	
	// before we blow the request buffer, check that the registration request will fit
	
	length = (Unsigned16)(1 + 1 + 1 + C1222_DEVICE_CLASS_LENGTH);
	length += C1222Misc_GetUIDLength(p->transportConfig.nodeApTitle);
	length += C1222Misc_GetUIDLength(p->transportConfig.esn);
	length += (Unsigned16)(1 + p->transportConfig.nativeAddressLength);
	length += (Unsigned16)3;
	
	if ( length > MAX_REGISTRATION_REQUEST )
	{
	    // set some kind of error!
	    return;
	}
    
    request[0] = 0x27;
    // <node-type> ::= <byte>
    request[1] = p->transportConfig.nodeType;
    // <connection-type> ::= <byte>
    request[2] = 0;  // assume we are connectionless until told otherwise
    
    memcpy(&request[3], p->transportConfig.deviceClass, C1222_DEVICE_CLASS_LENGTH);
    
    index = 3 + C1222_DEVICE_CLASS_LENGTH;
    
    // node aptitle
    
    length = C1222Misc_GetUIDLength(p->transportConfig.nodeApTitle);
    
    if ( length == 0 ) // normal
    {
        request[index++] = 0x0d;  // relative aptitle
        request[index++] = 0x00;  // zero length - is this how to do it?   
    }
    else // max length = 20
    {
        memcpy(&request[index], p->transportConfig.nodeApTitle, length);
        index += length;
    }
    
    // serial number
    
    length = C1222Misc_GetUIDLength(p->transportConfig.esn);
    
    if ( length == 0 ) // not good - we should have a serial number
    {
        request[index++] = 0x0d;  // relative aptitle
        request[index++] = 0x00;  // zero length - is this how to do it?   
    }
    else // max length = 20
    {
        memcpy(&request[index], p->transportConfig.esn, length);
        index += length;
    }
    
    // native address length and address (length is a byte not encoded ber)
    
    length = p->transportConfig.nativeAddressLength;
    request[index++] = length;
    memcpy(&request[index], p->transportConfig.nativeAddress, length);
    index += length;
    
    // suggested maximum re-registration period
    // software treats a suggested re-registration period of 0 as meaning the meter does not
    // support re-registration - so to be compatible I will set this to a large number.
    
    request[index++] = 0xFF;
    request[index++] = 0xFF;
    request[index++] = 0xFF;
    
    epsemBuffer[0] = 0x90; // response required, device class included
    memcpy( &epsemBuffer[1], p->transportConfig.deviceClass, 4);
    
    Epsem_Init(&epsem, epsemBuffer, sizeof(epsemBuffer));
    
    Epsem_AddRequestOrResponse(&epsem, request, index);

    relayAddressLength = p->registrationStatus.relayAddressLength;
    relayAddress = p->registrationStatus.relayNativeAddress;
    
    // now need to build acse message
    // calling aptitle is my aptitle (0 length until I get one)
    // called aptitle is the aptitle of the master relay (0 length if not yet assigned)
    // cannot be encrypted or authenticated since comm module does not know the keys
    
    pMsg = StartNewUnsegmentedMessage(p);
    
    pMsg->standardVersion = p->status.clientC1222StandardVersion;

    SetMessageDestination(p, relayAddressLength, relayAddress);
    
    // need called aptitle if not 0 length
    // need calling aptitle if not 0 length
    // need calling apinvocation id
    // need user information ( not encrypted )
    
    length = C1222Misc_GetUIDLength(p->transportConfig.masterRelayApTitle);
    if ( length > 2 )
    {
        C1222ApTitle_Construct(&apTitle, p->transportConfig.masterRelayApTitle, C1222_APTITLE_LENGTH);
        apTitle.length = length;
        
        ACSE_Message_SetCalledApTitle(pMsg, &apTitle);
    }

    length = C1222Misc_GetUIDLength(p->transportConfig.nodeApTitle);
    if ( length > 2 )
    {
        C1222ApTitle_Construct(&apTitle, p->transportConfig.nodeApTitle, C1222_APTITLE_LENGTH);
        apTitle.length = length;
        
        ACSE_Message_SetCallingApTitle(pMsg, &apTitle);
    }
    
    p->status.registrationRequestApInvocationId = C1222AL_GetNextApInvocationId(p);
    
    ACSE_Message_SetCallingApInvocationId(pMsg, p->status.registrationRequestApInvocationId);
    
    // assume there is enough room in our buffers for a registration request
    (void)ACSE_Message_SetUserInformation(pMsg, &epsem, FALSE); // no mac needed
    
    EndNewUnsegmentedMessage(p);
    
    // set the native address into the message receiver
    
    length = p->transportConfig.nativeAddressLength;
    
    if ( (length > 0)  && (length <= C1222_NATIVE_ADDRESS_LENGTH) )
    {
        p->messageReceiver.nativeAddressLength = length;
    
        memcpy(p->messageReceiver.nativeAddress, p->transportConfig.nativeAddress, length);
    }
    
    // the message is ready - let the app user have it
    
    C1222AL_IncrementStatistic(p, (Unsigned16)C1222_STATISTIC_NUMBER_OF_REGISTRATIONS_SENT);    
    
    C1222AL_NoteReceivedCompleteMessage(p); 
    
    p->status.sendingRegistrationRequest = TRUE;
}
Ejemplo n.º 2
0
Unsigned16 C1222Stack_GetNextApInvocationId(C1222Stack* p)
{
    return C1222AL_GetNextApInvocationId(&p->Xapplication);
}