📄 mdm.c
字号:
/***************************************************************************
*
* Copyright (c) 1997 - 2001 by Accelerated Technology, Inc.
*
* PROPRIETARY RIGHTS of Accelerated Technology are involved in the subject
* matter of this material. All manufacturing, reproduction, use and sales
* rights pertaining to this subject matter are governed by the license
* agreement. The recipient of this software implicity accepts the terms
* of the license.
*
****************************************************************************
****************************************************************************
*
* FILENAME VERSION
*
* MDM.C 2.4
*
* COMPONENT
*
* The modem control functionality of PPP.
*
* DESCRIPTION
*
* This file contains the modem functions.
*
*
* DATA STRUCTURES
*
* none
*
* FUNCTIONS
*
* MDM_Init
* MDM_Receive
* MDM_Data_Ready
* MDM_Get_Char
* MDM_Control_String
* MDM_Delay
* MDM_Dial
* MDM_Get_Modem_String
* MDM_Hangup
* MDM_Purge_Input_Buffer
* MDM_Change_Communication_Mode
* MDM_Wait_For_Client
* MDM_Modem_Connected
* MDM_Rings_To_Answer
*
* DEPENDENCIES
*
* string.h
* stdlib.h
* nucleus.h
* externs.h
* netevent.h
* tcp_errs.h
* ppp.h
*
*
****************************************************************************/
#include <string.h>
#include <stdlib.h>
#include "plus/nucleus.h"
#include "net/inc/externs.h"
#include "net/inc/netevent.h"
#include "net/inc/tcp_errs.h"
#include "net/inc/ncl.h"
#include "ppp/inc/nu_ppp.h"
#if (INCLUDE_PPP_MIB == NU_TRUE)
#include SNMP_GLUE
#endif
/***************************************************************************
* FUNCTION
*
* MDM_Init
*
* DESCRIPTION
*
* This function initializes the MODEM module.
*
* AUTHOR
*
* Uriah T. Pollock
*
* INPUTS
*
* none
*
* OUTPUTS
*
* STATUS Returns NU_SUCCESS if successful
* initialization, else a negative
* value is returned.
*
****************************************************************************/
STATUS MDM_Init(DV_DEVICE_ENTRY *dev_ptr)
{
LINK_LAYER *link_layer = (LINK_LAYER *)dev_ptr->dev_ppp_layer;
MDM_LAYER *mdm;
/* Allocate memory for the MDM layer structure. This structure will
be pointed to by the ppp_layer structure for this device. */
if (NU_Allocate_Memory (&System_Memory,
(VOID **)&mdm,
sizeof (MDM_LAYER),
NU_NO_SUSPEND
) != NU_SUCCESS)
{
NERRS_Log_Error (TCP_FATAL, __FILE__, __LINE__);
return(-1);
}
/* Zero out the hdlc layer information. */
UTL_Zero (mdm, sizeof (MDM_LAYER));
/* Store the address of the hdlc layer structure. */
link_layer->link = mdm;
/* Allocate a block of memory for the receive buffer. Not that this buffer
is only used when the driver is being used in terminal mode. */
if (NU_Allocate_Memory (&System_Memory,
(VOID **)&mdm->recv_buffer.mdm_head,
MDM_RECV_BUFFER_SIZE,
NU_NO_SUSPEND
) != NU_SUCCESS)
{
NERRS_Log_Error (NERR_FATAL, __FILE__, __LINE__);
return(-1);
}
mdm->recv_buffer.mdm_read =
mdm->recv_buffer.mdm_write =
mdm->recv_buffer.mdm_head;
mdm->recv_buffer.mdm_tail = mdm->recv_buffer.mdm_head +
MDM_RECV_BUFFER_SIZE - 1;
mdm->recv_buffer.mdm_buffer_status = MDM_BUFFER_EMPTY;
strcpy(mdm->dial_prefix, MDM_DIAL_PREFIX);
/* Set the default number of rings to answer the modem on. */
mdm->num_rings = MDM_RINGS_TO_ANSWER_ON;
return (NU_SUCCESS);
} /* end MDM_Init */
/***************************************************************************
* FUNCTION
*
* MDM_Receive
*
* DESCRIPTION
*
* This function receives characters whenever operating in terminal mode
*
* AUTHOR
*
* Uriah T. Pollock
*
* INPUTS
*
* none
*
* OUTPUTS
*
* none
*
*
****************************************************************************/
VOID MDM_Receive(DV_DEVICE_ENTRY *dev_ptr)
{
LINK_LAYER *link_layer = (LINK_LAYER *)dev_ptr->dev_ppp_layer;
MDM_LAYER *mdm = (MDM_LAYER*)link_layer->link;
URT_LAYER *uart = &link_layer->uart;
if (mdm->recv_buffer.mdm_buffer_status != MDM_BUFFER_FULL)
{
/* Get the character. */
*mdm->recv_buffer.mdm_write = URT_Get_Char(uart);
/* Point to the location where the next character will be written. */
mdm->recv_buffer.mdm_write++;
/* Does the write pointer need to be wrapped around to the start of the
ring buffer. */
if (mdm->recv_buffer.mdm_write > mdm->recv_buffer.mdm_tail)
mdm->recv_buffer.mdm_write = mdm->recv_buffer.mdm_head;
/* Set the status field. We just added some data so the buffer is
either full or contains at least one byte of data. */
if(mdm->recv_buffer.mdm_write == mdm->recv_buffer.mdm_read)
mdm->recv_buffer.mdm_buffer_status = MDM_BUFFER_FULL;
else
mdm->recv_buffer.mdm_buffer_status = MDM_BUFFER_DATA;
}
else
{
/* There is no space for the character, so drop it. */
URT_Get_Char(uart);
}
} /* end MDM_Receive */
/***************************************************************************
* FUNCTION
*
* MDM_Data_Ready
*
* DESCRIPTION
*
* This function checks to see if there are any characters in the
* receive buffer. A status value is returned indicating the whether
* characters are present in the receive buffer.
*
* AUTHOR
*
* Uriah T. Pollock
*
* INPUTS
*
* none
*
* OUTPUTS
*
* STATUS The status indicates the
* presence of characters.
*
****************************************************************************/
STATUS MDM_Data_Ready(CHAR *link_name)
{
DV_DEVICE_ENTRY *dev_ptr;
LINK_LAYER *link_layer;
MDM_LAYER *mdm;
/* Find the device for this name. */
dev_ptr = DEV_Get_Dev_By_Name (link_name);
/* Make sure that a device was found. */
if (dev_ptr)
{
/* Get the modem structure for this device. */
link_layer = (LINK_LAYER *)dev_ptr->dev_ppp_layer;
mdm = (MDM_LAYER*)link_layer->link;
if((mdm->recv_buffer.mdm_buffer_status == MDM_BUFFER_DATA) ||
(mdm->recv_buffer.mdm_buffer_status == MDM_BUFFER_FULL))
{
return (NU_TRUE);
}
else
return (NU_FALSE);
}
else
return (NU_INVALID_LINK);
} /* end MDM_Data_Ready */
/***************************************************************************
* FUNCTION
*
* MDM_Get_Char
*
* DESCRIPTION
*
* This function returns the next character that is in the receive
* buffer.
*
* AUTHOR
*
* Uriah T. Pollock
*
* INPUTS
*
* CHAR *c Pointer to a location to store
* the RX character.
*
* OUTPUTS
*
* STATUS NU_SUCCESS if a character is
* available. NU_NO_DATA if no
* characters are available.
* NU_INVALID_POINTER if c is NULL
*
****************************************************************************/
STATUS MDM_Get_Char(CHAR *c, CHAR *link_name)
{
STATUS ret_status;
DV_DEVICE_ENTRY *dev_ptr;
LINK_LAYER *link_layer;
MDM_LAYER *mdm;
if (c == NU_NULL)
return (NU_INVALID_POINTER);
/* Find the device for this name. */
dev_ptr = DEV_Get_Dev_By_Name (link_name);
/* Make sure that a device was found. */
if (dev_ptr)
{
/* Get the modem structure for this device. */
link_layer = (LINK_LAYER *)dev_ptr->dev_ppp_layer;
mdm = (MDM_LAYER*)link_layer->link;
/* Is there any data available. */
if ((mdm->recv_buffer.mdm_buffer_status == MDM_BUFFER_DATA) ||
(mdm->recv_buffer.mdm_buffer_status == MDM_BUFFER_FULL))
{
/* Store the character to be returned. */
*c = *mdm->recv_buffer.mdm_read;
/* Point to the next character to be removed from the buffer. */
mdm->recv_buffer.mdm_read++;
/* Does the read pointer need to be wrapped around to the start of the
buffer. */
if (mdm->recv_buffer.mdm_read > mdm->recv_buffer.mdm_tail)
mdm->recv_buffer.mdm_read = mdm->recv_buffer.mdm_head;
/* Set the status field. We just removed some data so the buffer is
either empty or is at least one byte of short of FULL. */
if(mdm->recv_buffer.mdm_write == mdm->recv_buffer.mdm_read)
mdm->recv_buffer.mdm_buffer_status = MDM_BUFFER_EMPTY;
else
mdm->recv_buffer.mdm_buffer_status = MDM_BUFFER_DATA;
ret_status = NU_SUCCESS;
}
else
{
ret_status = NU_NO_DATA;
}
}
else
ret_status = NU_INVALID_LINK;
return (ret_status);
} /* end MDM_Get_Char */
/***************************************************************************
* FUNCTION
*
* MDM_Control_String
*
* DESCRIPTION
*
* This function is used to send control codes to the modem.
*
* AUTHOR
*
* Uriah T. Pollock
*
* INPUTS
*
* CHAR *string String containing the control
* code to be sent.
*
* OUTPUTS
*
* STATUS NU_SUCCESS If successful
* NU_INVALID_POINTER If string
* pointer is null.
*
****************************************************************************/
STATUS MDM_Control_String(CHAR *string, CHAR *link_name)
{
DV_DEVICE_ENTRY *dev_ptr;
STATUS ret_status;
LINK_LAYER *link_layer;
URT_LAYER *uart;
if (string == NU_NULL)
return NU_INVALID_POINTER;
/* Find the device for this name. */
dev_ptr = DEV_Get_Dev_By_Name (link_name);
/* Make sure that the device was found. */
if (dev_ptr)
{
/* Get a pointer to the uart structure for this device. */
link_layer = (LINK_LAYER *)dev_ptr->dev_ppp_layer;
uart = &link_layer->uart;
while (*string) { /* loop for the entire string */
switch (*string) {
case '~': /* if ~, wait a half second */
MDM_Delay(500);
break;
default:
switch (*string) {
case '^': /* if ^, it's a control code */
if (string[1]) { /* send the control code */
string++;
URT_Put_Char((CHAR)(*string - 64), uart);
}
break;
default:
URT_Put_Char(*string, uart); /* send the character */
}
MDM_Delay(100); /* wait 100 ms. for slow modems */
}
string++; /* bump the string pointer */
} /* end while there are char to send */
ret_status = NU_SUCCESS;
} /* end if we got a device */
else
ret_status = NU_INVALID_LINK;
return (ret_status);
} /* MDM_Control_String */
/***************************************************************************
* FUNCTION
*
* MDM_Delay
*
* DESCRIPTION
*
* This function is used to simply consume CPU time.
*
* AUTHOR
*
* Uriah T. Pollock
*
* INPUTS
*
* UNSIGNED milliseconds Time in milliseconds to delay.
*
* OUTPUTS
*
* none
*
****************************************************************************/
VOID MDM_Delay(UNSIGNED milliseconds)
{
UNSIGNED ticks;
/* Compute the approximate number of ticks. This value does not have to be
exactly on target. */
ticks = (TICKS_PER_SECOND * milliseconds)/1000;
/* Sleep for at least one tick. */
if (!ticks)
ticks = 1;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -