Example #1
0
static ssize_t rmnet_ctl_write(struct file *file, const char __user * buf,
		size_t size, loff_t *pos)
{
	int			status;
	void			*wbuf;
	struct rmnet_ctrl_dev	*dev = file->private_data;

	if (!dev)
		return -ENODEV;

	if (size <= 0)
		return -EINVAL;

	if (!is_dev_connected(dev))
		return -ENETRESET;

	DBG("%s: Writing %i bytes on %s\n", __func__, size, dev->name);

	wbuf = kmalloc(size , GFP_KERNEL);
	if (!wbuf)
		return -ENOMEM;

	status = copy_from_user(wbuf , buf, size);
	if (status) {
		dev_err(dev->devicep,
		"%s: Unable to copy data from userspace %d\n",
		__func__, status);
		kfree(wbuf);
		return status;
	}
	DUMP_BUFFER("Write: ", size, buf);

	status = rmnet_usb_ctrl_write(dev, wbuf, size);
	if (status == size)
		return size;

	return status;
}
Example #2
0
static ACPI_STATUS
AcpiNsDumpOneObject (
    ACPI_HANDLE             ObjHandle,
    UINT32                  Level,
    void                    *Context,
    void                    **ReturnValue)
{
    ACPI_WALK_INFO          *Info = (ACPI_WALK_INFO *) Context;
    ACPI_NAMESPACE_NODE     *ThisNode;
    UINT8                   *Value;
    ACPI_OPERAND_OBJECT     *ObjDesc = NULL;
    ACPI_OBJECT_TYPE8       ObjType;
    ACPI_OBJECT_TYPE8       Type;
    UINT32                  BytesToDump;
    UINT32                  DownstreamSiblingMask = 0;
    UINT32                  LevelTmp;
    UINT32                  WhichBit;


    PROC_NAME ("NsDumpOneObject");


    ThisNode = AcpiNsConvertHandleToEntry (ObjHandle);

    LevelTmp    = Level;
    Type        = ThisNode->Type;
    WhichBit    = 1;


    if (!(AcpiDbgLevel & Info->DebugLevel))
    {
        return (AE_OK);
    }

    if (!ObjHandle)
    {
        ACPI_DEBUG_PRINT ((ACPI_DB_INFO, "Null object handle\n"));
        return (AE_OK);
    }

    /* Check if the owner matches */

    if ((Info->OwnerId != ACPI_UINT32_MAX) &&
        (Info->OwnerId != ThisNode->OwnerId))
    {
        return (AE_OK);
    }


    /* Indent the object according to the level */

    while (LevelTmp--)
    {

        /* Print appropriate characters to form tree structure */

        if (LevelTmp)
        {
            if (DownstreamSiblingMask & WhichBit)
            {
                ACPI_DEBUG_PRINT_RAW ((ACPI_DB_TABLES, "|"));
            }

            else
            {
                ACPI_DEBUG_PRINT_RAW ((ACPI_DB_TABLES, " "));
            }

            WhichBit <<= 1;
        }

        else
        {
            if (AcpiNsExistDownstreamSibling (ThisNode + 1))
            {
                DownstreamSiblingMask |= (1 << (Level - 1));
                ACPI_DEBUG_PRINT_RAW ((ACPI_DB_TABLES, "+"));
            }

            else
            {
                DownstreamSiblingMask &= ACPI_UINT32_MAX ^ (1 << (Level - 1));
                ACPI_DEBUG_PRINT_RAW ((ACPI_DB_TABLES, "+"));
            }

            if (ThisNode->Child == NULL)
            {
                ACPI_DEBUG_PRINT_RAW ((ACPI_DB_TABLES, "-"));
            }

            else if (AcpiNsExistDownstreamSibling (ThisNode->Child))
            {
                ACPI_DEBUG_PRINT_RAW ((ACPI_DB_TABLES, "+"));
            }

            else
            {
                ACPI_DEBUG_PRINT_RAW ((ACPI_DB_TABLES, "-"));
            }
        }
    }


    /* Check the integrity of our data */

    if (Type > INTERNAL_TYPE_MAX)
    {
        Type = INTERNAL_TYPE_DEF_ANY;                                /* prints as *ERROR* */
    }

    if (!AcpiUtValidAcpiName (ThisNode->Name))
    {
        REPORT_WARNING (("Invalid ACPI Name %08X\n", ThisNode->Name));
    }

    /*
     * Now we can print out the pertinent information
     */
    ACPI_DEBUG_PRINT_RAW ((ACPI_DB_TABLES, " %4.4s %-9s ", &ThisNode->Name, AcpiUtGetTypeName (Type)));
    ACPI_DEBUG_PRINT_RAW ((ACPI_DB_TABLES, "%p S:%p O:%p",  ThisNode, ThisNode->Child, ThisNode->Object));


    if (!ThisNode->Object)
    {
        /* No attached object, we are done */

        ACPI_DEBUG_PRINT_RAW ((ACPI_DB_TABLES, "\n"));
        return (AE_OK);
    }

    switch (Type)
    {

    case ACPI_TYPE_METHOD:

        /* Name is a Method and its AML offset/length are set */

        ACPI_DEBUG_PRINT_RAW ((ACPI_DB_TABLES, " M:%p-%X\n",
                    ((ACPI_OPERAND_OBJECT  *) ThisNode->Object)->Method.Pcode,
                    ((ACPI_OPERAND_OBJECT  *) ThisNode->Object)->Method.PcodeLength));

        break;


    case ACPI_TYPE_INTEGER:

        ACPI_DEBUG_PRINT_RAW ((ACPI_DB_TABLES, " N:%X\n",
                    ((ACPI_OPERAND_OBJECT  *) ThisNode->Object)->Integer.Value));
        break;


    case ACPI_TYPE_STRING:

        ACPI_DEBUG_PRINT_RAW ((ACPI_DB_TABLES, " S:%p-%X\n",
                    ((ACPI_OPERAND_OBJECT  *) ThisNode->Object)->String.Pointer,
                    ((ACPI_OPERAND_OBJECT  *) ThisNode->Object)->String.Length));
        break;


    case ACPI_TYPE_BUFFER:

        ACPI_DEBUG_PRINT_RAW ((ACPI_DB_TABLES, " B:%p-%X\n",
                    ((ACPI_OPERAND_OBJECT  *) ThisNode->Object)->Buffer.Pointer,
                    ((ACPI_OPERAND_OBJECT  *) ThisNode->Object)->Buffer.Length));
        break;


    default:

        ACPI_DEBUG_PRINT_RAW ((ACPI_DB_TABLES, "\n"));
        break;
    }

    /* If debug turned off, done */

    if (!(AcpiDbgLevel & ACPI_LV_VALUES))
    {
        return (AE_OK);
    }


    /* If there is an attached object, display it */

    Value = ThisNode->Object;

    /* Dump attached objects */

    while (Value)
    {
        ObjType = INTERNAL_TYPE_INVALID;

        /* Decode the type of attached object and dump the contents */

        ACPI_DEBUG_PRINT_RAW ((ACPI_DB_TABLES, "        Attached Object %p: ", Value));

        if (AcpiTbSystemTablePointer (Value))
        {
            ACPI_DEBUG_PRINT_RAW ((ACPI_DB_TABLES, "(Ptr to AML Code)\n"));
            BytesToDump = 16;
        }

        else if (VALID_DESCRIPTOR_TYPE (Value, ACPI_DESC_TYPE_NAMED))
        {
            ACPI_DEBUG_PRINT_RAW ((ACPI_DB_TABLES, "(Ptr to Node)\n"));
            BytesToDump = sizeof (ACPI_NAMESPACE_NODE);
        }


        else if (VALID_DESCRIPTOR_TYPE (Value, ACPI_DESC_TYPE_INTERNAL))
        {
            ObjDesc = (ACPI_OPERAND_OBJECT  *) Value;
            ObjType = ObjDesc->Common.Type;

            if (ObjType > INTERNAL_TYPE_MAX)
            {
                ACPI_DEBUG_PRINT_RAW ((ACPI_DB_TABLES, "(Ptr to ACPI Object type %X [UNKNOWN])\n", ObjType));
                BytesToDump = 32;
            }

            else
            {
                ACPI_DEBUG_PRINT_RAW ((ACPI_DB_TABLES, "(Ptr to ACPI Object type %X [%s])\n",
                                    ObjType, AcpiUtGetTypeName (ObjType)));
                BytesToDump = sizeof (ACPI_OPERAND_OBJECT);
            }
        }

        else
        {
            ACPI_DEBUG_PRINT_RAW ((ACPI_DB_TABLES, "(String or Buffer - not descriptor)\n", Value));
            BytesToDump = 16;
        }

        DUMP_BUFFER (Value, BytesToDump);

        /* If value is NOT an internal object, we are done */

        if ((AcpiTbSystemTablePointer (Value)) ||
            (VALID_DESCRIPTOR_TYPE (Value, ACPI_DESC_TYPE_NAMED)))
        {
            goto Cleanup;
        }

        /*
         * Valid object, get the pointer to next level, if any
         */
        switch (ObjType)
        {
        case ACPI_TYPE_STRING:
            Value = (UINT8 *) ObjDesc->String.Pointer;
            break;

        case ACPI_TYPE_BUFFER:
            Value = (UINT8 *) ObjDesc->Buffer.Pointer;
            break;

        case ACPI_TYPE_BUFFER_FIELD:
            Value = (UINT8 *) ObjDesc->BufferField.BufferObj;
            break;

        case ACPI_TYPE_PACKAGE:
            Value = (UINT8 *) ObjDesc->Package.Elements;
            break;

        case ACPI_TYPE_METHOD:
            Value = (UINT8 *) ObjDesc->Method.Pcode;
            break;

        case INTERNAL_TYPE_REGION_FIELD:
            Value = (UINT8 *) ObjDesc->Field.RegionObj;
            break;

        case INTERNAL_TYPE_BANK_FIELD:
            Value = (UINT8 *) ObjDesc->BankField.RegionObj;
            break;

        case INTERNAL_TYPE_INDEX_FIELD:
            Value = (UINT8 *) ObjDesc->IndexField.IndexObj;
            break;

       default:
            goto Cleanup;
        }

        ObjType = INTERNAL_TYPE_INVALID;     /* Terminate loop after next pass */
    }

Cleanup:
    ACPI_DEBUG_PRINT_RAW ((ACPI_DB_TABLES, "\n"));
    return (AE_OK);
}
Example #3
0
File: proxy.c Project: OPSF/uClinux
/*
 * PROXY_REWRITE_INVITATION_BODY
 *
 * rewrites the outgoing INVITATION request or response packet
 * 
 * RETURNS
 *	STS_SUCCESS on success
 *	STS_FAILURE on error
 */
int proxy_rewrite_invitation_body(osip_message_t *mymsg, int direction){
   osip_body_t *body;
   sdp_message_t  *sdp;
   struct in_addr map_addr, addr_sess, addr_media, outside_addr, inside_addr;
   int sts;
   char *bodybuff;
   int bodybuflen;
   char clen[8]; /* content length: probably never more than 7 digits !*/
   int map_port, msg_port;
   int media_stream_no;
   sdp_connection_t *sdp_conn;
   sdp_media_t *sdp_med;
   int rtp_direction=0;
   int have_c_media=0;

   if (configuration.rtp_proxy_enable == 0) return STS_SUCCESS;

   /*
    * get SDP structure
    */
   sts = osip_message_get_body(mymsg, 0, &body);
   if (sts != 0) {
#if 0
      if ((MSG_IS_RESPONSE_FOR(mymsg,"INVITE")) &&
          (MSG_IS_STATUS_1XX(mymsg))) {
         /* 1xx responses *MAY* contain SDP data */
         DEBUGC(DBCLASS_PROXY, "rewrite_invitation_body: "
                "no body found in message");
         return STS_SUCCESS;
      } else {
         /* INVITE request and 200 response *MUST* contain SDP data */
         ERROR("rewrite_invitation_body: no body found in message");
         return STS_FAILURE;
      }
#else
      DEBUGC(DBCLASS_PROXY, "rewrite_invitation_body: "
                            "no body found in message");
      return STS_SUCCESS;
#endif
   }

   sts = sip_body_to_str(body, &bodybuff, &bodybuflen);
   if (sts != 0) {
      ERROR("rewrite_invitation_body: unable to sip_body_to_str");
   }
   sts = sdp_message_init(&sdp);
   sts = sdp_message_parse (sdp, bodybuff);
   if (sts != 0) {
      ERROR("rewrite_invitation_body: unable to sdp_message_parse body");
      DUMP_BUFFER(-1, bodybuff, bodybuflen);
      osip_free(bodybuff);
      sdp_message_free(sdp);
      return STS_FAILURE;
   }
   osip_free(bodybuff);


if (configuration.debuglevel)
{ /* just dump the buffer */
   char *tmp, *tmp2;
   int tmplen;
   sts = osip_message_get_body(mymsg, 0, &body);
   sts = sip_body_to_str(body, &tmp, &tmplen);
   osip_content_length_to_str(mymsg->content_length, &tmp2);
   DEBUG("Body before rewrite (clen=%s, strlen=%i):\n%s\n----",
         tmp2, tmplen, tmp);
   osip_free(tmp);
   osip_free(tmp2);
}

   /*
    * RTP proxy: get ready and start forwarding
    * start forwarding for each media stream ('m=' item in SIP message)
    */

   /* get outbound address */
   if (get_interface_ip(IF_OUTBOUND, &outside_addr) != STS_SUCCESS) {
      sdp_message_free(sdp);
      return STS_FAILURE;
   }

   /* get inbound address */
   if (get_interface_ip(IF_INBOUND, &inside_addr) != STS_SUCCESS) {
      sdp_message_free(sdp);
      return STS_FAILURE;
   }

   /* figure out what address to use for RTP masquerading */
   if (MSG_IS_REQUEST(mymsg)) {
      if (direction == DIR_INCOMING) {
         memcpy(&map_addr, &inside_addr, sizeof (map_addr));
         rtp_direction = DIR_OUTGOING;
      } else {
         memcpy(&map_addr, &outside_addr, sizeof (map_addr));
         rtp_direction = DIR_INCOMING;
      }
   } else /* MSG_IS_REPONSE(mymsg) */ {
      if (direction == DIR_INCOMING) {
         memcpy(&map_addr, &inside_addr, sizeof (map_addr));
         rtp_direction = DIR_OUTGOING;
      } else {
         memcpy(&map_addr, &outside_addr, sizeof (map_addr));
         rtp_direction = DIR_INCOMING;
      }
   }

   DEBUGC(DBCLASS_PROXY, "proxy_rewrite_invitation_body: SIP[%s %s] RTP[%s %s]",
          MSG_IS_REQUEST(mymsg)? "RQ" : "RS",
          (direction==DIR_INCOMING)? "IN" : "OUT",
          (rtp_direction==DIR_INCOMING)? "IN" : "OUT",
          utils_inet_ntoa(map_addr));


   /*
    * first, check presence of a 'c=' item on session level
    */
   if (sdp->c_connection==NULL || sdp->c_connection->c_addr==NULL) {
      /*
       * No 'c=' on session level, search on media level now
       *
       * According to RFC2327, ALL media description must
       * include a 'c=' item now:
       */
      media_stream_no=0;
      while (!sdp_message_endof_media(sdp, media_stream_no)) {
         /* check if n'th media stream is present */
         if (sdp_message_c_addr_get(sdp, media_stream_no, 0) == NULL) {
            ERROR("SDP: have no 'c=' on session level and neither "
                  "on media level (media=%i)",media_stream_no);
            sdp_message_free(sdp);
            return STS_FAILURE;
         }
         media_stream_no++;
      } /* while */
   }

   /* Required 'c=' items ARE present */


   /*
    * rewrite 'c=' item on session level if present and not yet done.
    * remember the original address in addr_sess
    */
   memset(&addr_sess, 0, sizeof(addr_sess));
   if (sdp->c_connection && sdp->c_connection->c_addr) {
      sts = get_ip_by_host(sdp->c_connection->c_addr, &addr_sess);
      if (sts == STS_FAILURE) {
         ERROR("SDP: cannot resolve session 'c=' host [%s]",
               sdp->c_connection->c_addr);
         sdp_message_free(sdp);
         return STS_FAILURE;
      }
      /*
       * Rewrite
       * an IP address of 0.0.0.0 means *MUTE*, don't rewrite such
       */
      if (strcmp(sdp->c_connection->c_addr, "0.0.0.0") != 0) {
         osip_free(sdp->c_connection->c_addr);
         sdp->c_connection->c_addr=osip_malloc(HOSTNAME_SIZE);
         sprintf(sdp->c_connection->c_addr, "%s", utils_inet_ntoa(map_addr));
      } else {
         /* 0.0.0.0 - don't rewrite */
         DEBUGC(DBCLASS_PROXY, "proxy_rewrite_invitation_body: "
                "got a MUTE c= record (on session level - legal?)");
      }
   }


   /*
    * rewrite 'o=' item (originator) on session level if present.
    */
   if (sdp->o_addrtype && sdp->o_addr) {
      if (strcmp(sdp->o_addrtype, "IP4") != 0) {
         ERROR("got IP6 in SDP originator - not yet suported by siproxd");
         sdp_message_free(sdp);
         return STS_FAILURE;
      }

      osip_free(sdp->o_addr);
      sdp->o_addr=osip_malloc(HOSTNAME_SIZE);
      sprintf(sdp->o_addr, "%s", utils_inet_ntoa(map_addr));
   }


   /*
    * loop through all media descritions,
    * start RTP proxy and rewrite them
    */
   for (media_stream_no=0;;media_stream_no++) {
      /* check if n'th media stream is present */
      if (sdp_message_m_port_get(sdp, media_stream_no) == NULL) break;

      /*
       * check if a 'c=' item is present in this media description,
       * if so -> rewrite it
       */
      memset(&addr_media, 0, sizeof(addr_media));
      have_c_media=0;
      sdp_conn=sdp_message_connection_get(sdp, media_stream_no, 0);
      if (sdp_conn && sdp_conn->c_addr) {
         if (strcmp(sdp_conn->c_addr, "0.0.0.0") != 0) {
            sts = get_ip_by_host(sdp_conn->c_addr, &addr_media);
            have_c_media=1;
            /* have a valid address */
            osip_free(sdp_conn->c_addr);
            sdp_conn->c_addr=osip_malloc(HOSTNAME_SIZE);
            sprintf(sdp_conn->c_addr, "%s", utils_inet_ntoa(map_addr));
         } else {
            /* 0.0.0.0 - don't rewrite */
            DEBUGC(DBCLASS_PROXY, "proxy_rewrite_invitation_body: got a "
                   "MUTE c= record (media level)");
         }
      }

      /* start an RTP proxying stream */
      if (sdp_message_m_port_get(sdp, media_stream_no)) {
         msg_port=atoi(sdp_message_m_port_get(sdp, media_stream_no));

         if (msg_port > 0) {
            osip_uri_t *cont_url = NULL;
            char *client_id=NULL;
            /* try to get some additional UA specific unique ID.
             * Try:
             * 1) User part of Contact header
             * 2) Host part of Contact header (will be different
             *    between internal UA and external UA)
             */
            if (!osip_list_eol(mymsg->contacts, 0))
               cont_url = ((osip_contact_t*)(mymsg->contacts->node->element))->url;
            if (cont_url) {
               client_id=cont_url->username;
               if (client_id == NULL) client_id=cont_url->host;
            }


            /*
             * do we have a 'c=' item on media level?
             * if not, use the same as on session level
             */
            if (have_c_media == 0) {
               memcpy(&addr_media, &addr_sess, sizeof(addr_sess));
            }

            /*
             * Am I running in front of the routing device? Then I cannot
             * use the external IP to bind a listen socket to, so force
             * the use of my inbound IP for listening.
             */
            if ((rtp_direction == DIR_INCOMING) &&
                (configuration.outbound_host) &&
                (strcmp(configuration.outbound_host, "")!=0)) {
               DEBUGC(DBCLASS_PROXY, "proxy_rewrite_invitation_body: "
                      "in-front-of-NAT-Router");
               memcpy(&map_addr, &inside_addr, sizeof (map_addr));
            }

            sts = rtp_start_fwd(osip_message_get_call_id(mymsg),
                                client_id,
                                rtp_direction,
                                media_stream_no,
                                map_addr, &map_port,
                                addr_media, msg_port);

            if (sts == STS_SUCCESS) {
               /* and rewrite the port */
               sdp_med=osip_list_get(sdp->m_medias, media_stream_no);
               if (sdp_med && sdp_med->m_port) {
                  osip_free(sdp_med->m_port);
                  sdp_med->m_port=osip_malloc(8); /* 5 digits, \0 + align */
                  sprintf(sdp_med->m_port, "%i", map_port);
                  DEBUGC(DBCLASS_PROXY, "proxy_rewrite_invitation_body: "
                         "m= rewrote port to [%i]",map_port);
               } else {
                  ERROR("rewriting port in m= failed sdp_med=%p, "
                        "m_number_of_port=%p", sdp_med, sdp_med->m_port);
               }
            } /* sts == success */
         } /* if msg_port > 0 */
      } else {
         /* no port defined - skip entry */
         WARN("no port defined in m=(media) stream_no=%i", media_stream_no);
         continue;
      }
   } /* for media_stream_no */

   /* remove old body */
   sts = osip_list_remove(mymsg->bodies, 0);
   osip_body_free(body);

   /* dump new body */
   sdp_message_to_str(sdp, &bodybuff);
   bodybuflen=strlen(bodybuff);

   /* free sdp structure */
   sdp_message_free(sdp);

   /* include new body */
   sip_message_set_body(mymsg, bodybuff, bodybuflen);
   if (sts != 0) {
      ERROR("rewrite_invitation_body: unable to sip_message_set_body body");
   }

   /* free content length resource and include new one*/
   osip_content_length_free(mymsg->content_length);
   mymsg->content_length=NULL;
   sprintf(clen,"%i",bodybuflen);
   sts = osip_message_set_content_length(mymsg, clen);

   /* free old body */
   osip_free(bodybuff);

if (configuration.debuglevel)
{ /* just dump the buffer */
   char *tmp, *tmp2;
   int tmplen;
   sts = osip_message_get_body(mymsg, 0, &body);
   sts = sip_body_to_str(body, &tmp, &tmplen);
   osip_content_length_to_str(mymsg->content_length, &tmp2);
   DEBUG("Body after rewrite (clen=%s, strlen=%i):\n%s\n----",
         tmp2, tmplen, tmp);
   osip_free(tmp);
   osip_free(tmp2);
}
   return STS_SUCCESS;
}
Example #4
0
ACPI_STATUS
AcpiDbLoadTable(
    FILE                    *fp,
    ACPI_TABLE_HEADER       **TablePtr,
    UINT32                  *TableLength)
{
    ACPI_TABLE_HEADER       TableHeader;
    UINT8                   *AmlPtr;
    UINT32                  AmlLength;
    UINT32                  Actual;
    ACPI_STATUS             Status;


    /* Read the table header */

    if (fread (&TableHeader, 1, sizeof (TableHeader), fp) != sizeof (ACPI_TABLE_HEADER))
    {
        AcpiOsPrintf ("Couldn't read the table header\n");
        return (AE_BAD_SIGNATURE);
    }


    /* Validate the table header/length */

    Status = AcpiTbValidateTableHeader (&TableHeader);
    if ((ACPI_FAILURE (Status)) ||
        (TableHeader.Length > 524288))  /* 1/2 Mbyte should be enough */
    {
        AcpiOsPrintf ("Table header is invalid!\n");
        return (AE_ERROR);
    }


    /* We only support a limited number of table types */

    if (STRNCMP ((char *) TableHeader.Signature, DSDT_SIG, 4) &&
        STRNCMP ((char *) TableHeader.Signature, PSDT_SIG, 4) &&
        STRNCMP ((char *) TableHeader.Signature, SSDT_SIG, 4))
    {
        AcpiOsPrintf ("Table signature is invalid\n");
        DUMP_BUFFER (&TableHeader, sizeof (ACPI_TABLE_HEADER));
        return (AE_ERROR);
    }

    /* Allocate a buffer for the table */

    *TableLength = TableHeader.Length;
    *TablePtr = ACPI_MEM_ALLOCATE ((size_t) *TableLength);
    if (!*TablePtr)
    {
        AcpiOsPrintf ("Could not allocate memory for ACPI table %4.4s (size=%X)\n",
                    TableHeader.Signature, TableHeader.Length);
        return (AE_NO_MEMORY);
    }


    AmlPtr      = (UINT8 *) *TablePtr + sizeof (TableHeader);
    AmlLength   = *TableLength - sizeof (TableHeader);

    /* Copy the header to the buffer */

    MEMCPY (*TablePtr, &TableHeader, sizeof (TableHeader));

    /* Get the rest of the table */

    Actual = fread (AmlPtr, 1, (size_t) AmlLength, fp);
    if (Actual == AmlLength)
    {
        return (AE_OK);
    }

    if (Actual > 0)
    {
        AcpiOsPrintf ("Warning - reading table, asked for %X got %X\n", AmlLength, Actual);
       return (AE_OK);
    }


    AcpiOsPrintf ("Error - could not read the table file\n");
    ACPI_MEM_FREE (*TablePtr);
    *TablePtr = NULL;
    *TableLength = 0;

    return (AE_ERROR);
}
Example #5
0
static ssize_t rmnet_ctl_read(struct file *file, char __user *buf, size_t count,
		loff_t *ppos)
{
	int				retval = 0;
	int				bytes_to_read;
	struct rmnet_ctrl_dev		*dev;
	struct ctrl_pkt_list_elem	*list_elem = NULL;
	unsigned long			flags;
	char temp[100];

	dev = file->private_data;
	if (!dev)
		return -ENODEV;

	DBG("%s: Read from %s\n", __func__, dev->name);

ctrl_read:
	if (!is_dev_connected(dev)) {
		dev_dbg(dev->devicep, "%s: Device not connected\n",
			__func__);
		return -ENETRESET;
	}
	spin_lock_irqsave(&dev->rx_lock, flags);
	if (list_empty(&dev->rx_list)) {
		spin_unlock_irqrestore(&dev->rx_lock, flags);

		retval = wait_event_interruptible(dev->read_wait_queue,
					!list_empty(&dev->rx_list) ||
					!is_dev_connected(dev));
		if (retval < 0)
			return retval;

		goto ctrl_read;
	}

	list_elem = list_first_entry(&dev->rx_list,
				     struct ctrl_pkt_list_elem, list);
	bytes_to_read = (uint32_t)(list_elem->cpkt.data_size);
	if (bytes_to_read > count) {
		spin_unlock_irqrestore(&dev->rx_lock, flags);
		dev_err(dev->devicep, "%s: Packet size %d > buf size %d\n",
			__func__, bytes_to_read, count);
		return -ENOMEM;
	}
	spin_unlock_irqrestore(&dev->rx_lock, flags);

	if (copy_to_user(buf, list_elem->cpkt.data, bytes_to_read)) {
			dev_err(dev->devicep,
				"%s: copy_to_user failed for %s\n",
				__func__, dev->name);
		return -EFAULT;
	}
	spin_lock_irqsave(&dev->rx_lock, flags);
	list_del(&list_elem->list);
	spin_unlock_irqrestore(&dev->rx_lock, flags);

	kfree(list_elem->cpkt.data);
	kfree(list_elem);
	DBG("%s: Returning %d bytes to %s\n", __func__, bytes_to_read,
			dev->name);

	snprintf(temp, sizeof(temp), "[%lluns]READ :", rd_poll_delta_time);
	DUMP_BUFFER(temp, bytes_to_read, buf);

	return bytes_to_read;
}
static ssize_t rmnet_ctl_write(struct file *file, const char __user * buf,
		size_t size, loff_t *pos)
{
	int			status;
	size_t			total_len;
	void			*wbuf;
	void			*actual_data;
	struct ctrl_pkt		*cpkt;
	struct rmnet_ctrl_dev	*dev = file->private_data;

rewrite:
	if (!dev)
		return -ENODEV;

	if (!size)
		return -EINVAL;

	if (!test_bit(RMNET_CTRL_DEV_READY, &dev->status))
		return -ENETRESET;

	DBG("%s: Writing %i bytes on %s\n", __func__, size, dev->name);

	total_len = size;

	if (test_bit(RMNET_CTRL_DEV_MUX_EN, &dev->status))
		total_len += sizeof(struct mux_hdr) + MAX_PAD_BYTES(4);

	wbuf = kmalloc(total_len , GFP_KERNEL);
	if (!wbuf)
		return -ENOMEM;

	cpkt = kmalloc(sizeof(struct ctrl_pkt), GFP_KERNEL);
	if (!cpkt) {
		kfree(wbuf);
		return -ENOMEM;
	}
	actual_data = cpkt->data = wbuf;
	cpkt->data_size = total_len;
	cpkt->ctxt = dev;

	if (test_bit(RMNET_CTRL_DEV_MUX_EN, &dev->status)) {
		actual_data = wbuf + sizeof(struct mux_hdr);
		rmnet_usb_ctrl_mux(dev->ch_id, cpkt);
	}

	status = copy_from_user(actual_data, buf, size);
	if (status) {
		dev_err(dev->devicep,
		"%s: Unable to copy data from userspace %d\n",
		__func__, status);
		kfree(wbuf);
		kfree(cpkt);
		return status;
	}
	DUMP_BUFFER("Write: ", size, buf);

	status = rmnet_usb_ctrl_write(dev, cpkt, size);
	if (status == size)
		return size;
	else if (status == -EAGAIN) {
		dev_err(dev->devicep, "%s: rewrite\n", __func__);
		goto rewrite;
	}

	return status;
}
Example #7
0
// TODO: these tests suck
bool
test_buffer_printf () {
	size_t n = 0;
	buffer_t *buf = buffer_new();

	if (!buf) {
		FAIL("buffer_new() failed\n");
	}

	n = buffer_printf(buf, "%s", "Hello, world!");
	DUMP_BUFFER();
	printf("n: %lu, strlen(\"Hello, world!\"): %lu\n", n, strlen("Hello, world!"));
	if (n != strlen("Hello, world!")) {
		FAIL("buffer_printf() \"Hello world!\" failed\n");
	}


	n = buffer_printf(buf, "%d %d", 345, 543);
	DUMP_BUFFER();
	printf("n: %lu, strlen(\"345 543\"): %lu\n", n, strlen("345 543"));
	if (n != strlen("345 543")) {
		FAIL("buffer_printf() \"345 543\" failed\n");
	}


	n = buffer_printf(buf, "%s",
		"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
		"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
		"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
		"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
		"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
		"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
		"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
		"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
		"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
		"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
		"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
		"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
		"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
		"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
		"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
		"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
		"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
	);
	DUMP_BUFFER();

	if (n !=
		strlen(
			"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
			"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
			"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
			"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
			"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
			"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
			"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
			"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
			"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
			"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
			"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
			"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
			"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
			"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
			"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
			"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
			"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
		)
	) {
		FAIL("buffer_printf() - big print failed");
	}

	PASS();
}
Example #8
0
int main (int argc, char *argv[]) 
{
   int sts;
   int i;
   int buflen;
   int access;
   char buff [BUFFER_SIZE];
   sip_ticket_t ticket;

   extern char *optarg;         /* Defined in libc getopt and unistd.h */
   int ch1;
   
   char configfile[64]="siproxd";       /* basename of configfile */
   int  config_search=1;                /* search the config file */
   int  cmdline_debuglevel=0;
   char *pidfilename=NULL;
   struct sigaction act;

   log_set_stderr(1);

/*
 * setup signal handlers
 */
   act.sa_handler=sighandler;
   sigemptyset(&act.sa_mask);
   act.sa_flags=SA_RESTART;
   if (sigaction(SIGTERM, &act, NULL)) {
      ERROR("Failed to install SIGTERM handler");
   }
   if (sigaction(SIGINT, &act, NULL)) {
      ERROR("Failed to install SIGINT handler");
   }
   if (sigaction(SIGUSR2, &act, NULL)) {
      ERROR("Failed to install SIGUSR2 handler");
   }


/*
 * prepare default configuration
 */
   make_default_config();

   log_set_pattern(configuration.debuglevel);

/*
 * parse command line
 */
{
#ifdef  HAVE_GETOPT_LONG
   int option_index = 0;
   static struct option long_options[] = {
      {"help", no_argument, NULL, 'h'},
      {"config", required_argument, NULL, 'c'},
      {"debug", required_argument, NULL, 'd'},
      {"pid-file", required_argument, NULL,'p'},
      {0,0,0,0}
   };

    while ((ch1 = getopt_long(argc, argv, "hc:d:p:",
                  long_options, &option_index)) != -1) {
#else   /* ! HAVE_GETOPT_LONG */
    while ((ch1 = getopt(argc, argv, "hc:d:p:")) != -1) {
#endif
      switch (ch1) {
      case 'h': /* help */
         DEBUGC(DBCLASS_CONFIG,"option: help");
         fprintf(stderr,str_helpmsg);
         exit(0);
         break;

      case 'c': /* load config file */
         DEBUGC(DBCLASS_CONFIG,"option: config file=%s",optarg);
         i=sizeof(configfile)-1;
         strncpy(configfile,optarg,i-1);
         configfile[i]='\0';
         config_search=0;
         break; 

      case 'd': /* set debug level */
         DEBUGC(DBCLASS_CONFIG,"option: set debug level: %s",optarg);
         cmdline_debuglevel=atoi(optarg);
         log_set_pattern(cmdline_debuglevel);
         break;

      case 'p':
         pidfilename = optarg;
         break;

      default:
         DEBUGC(DBCLASS_CONFIG,"no command line options");
         break; 
      }
   }
}

/*
 * Init stuff
 */
   INFO(PACKAGE"-"VERSION"-"BUILDSTR" "UNAME" starting up");

   /* read the config file */
   if (read_config(configfile, config_search) == STS_FAILURE) exit(1);

   /* if a debug level > 0 has been given on the commandline use its
      value and not what is in the config file */
   if (cmdline_debuglevel != 0) {
      configuration.debuglevel=cmdline_debuglevel;
   }

/*
 * open a the pwfile instance, so we still have access after
 * we possibly have chroot()ed to somewhere.
 */
   if (configuration.proxy_auth_pwfile) {
      siproxd_passwordfile = fopen(configuration.proxy_auth_pwfile, "r");
   } else {
      siproxd_passwordfile = NULL;
   }

   /* set debug level as desired */
   log_set_pattern(configuration.debuglevel);
   log_set_listen_port(configuration.debugport);

   /* change user and group IDs */
   secure_enviroment();

   /* daemonize if requested to */
   if (configuration.daemonize) {
      DEBUGC(DBCLASS_CONFIG,"daemonizing");
      if (fork()!=0) exit(0);
      setsid();
      if (fork()!=0) exit(0);

      log_set_stderr(0);
      INFO("daemonized, pid=%i", getpid());
   }

   /* write PID file of main thread */
   if (pidfilename == NULL) pidfilename = configuration.pid_file;
   if (pidfilename) {
      FILE *pidfile;
      DEBUGC(DBCLASS_CONFIG,"creating PID file [%s]", pidfilename);
      sts=unlink(configuration.pid_file);
      if ((sts==0) ||(errno == ENOENT)) {
         if ((pidfile=fopen(pidfilename, "w"))) {
            fprintf(pidfile,"%i\n",(int)getpid());
            fclose(pidfile);
         } else {
            WARN("couldn't create new PID file: %s", strerror(errno));
         }
      } else {
         WARN("couldn't delete old PID file: %s", strerror(errno));
      }
   }

   /* initialize the RTP proxy */
   sts=rtpproxy_init();
   if (sts != STS_SUCCESS) {
      ERROR("unable to initialize RTP proxy - aborting"); 
      exit(1);
   }

   /* init the oSIP parser */
   parser_init();

   /* listen for incoming messages */
   sts=sipsock_listen();
   if (sts == STS_FAILURE) {
      /* failure to allocate SIP socket... */
      ERROR("unable to bind to SIP listening socket - aborting"); 
      exit(1);
   }

   /* initialize the registration facility */
   register_init();

/*
 * silence the log - if so required...
 */
   log_set_silence(configuration.silence_log);

   INFO(PACKAGE"-"VERSION"-"BUILDSTR" "UNAME" started");

/*****************************
 * Main loop
 *****************************/
   while (!exit_program) {

      DEBUGC(DBCLASS_BABBLE,"going into sipsock_wait\n");
      while (sipsock_wait()<=0) {
         /* got no input, here by timeout. do aging */
         register_agemap();

         /* TCP log: check for a connection */
         log_tcp_connect();

         /* dump memory stats if requested to do so */
         if (dmalloc_dump) {
            dmalloc_dump=0;
#ifdef DMALLOC
            INFO("SIGUSR2 - DMALLOC statistics is dumped");
            dmalloc_log_stats();
            dmalloc_log_unfreed();
#else
            INFO("SIGUSR2 - DMALLOC support is not compiled in");
#endif
         }

         if (exit_program) goto exit_prg;
      }

      /*
       * got input, process
       */
      DEBUGC(DBCLASS_BABBLE,"back from sipsock_wait");
      ticket.direction=0;

      buflen=sipsock_read(&buff, sizeof(buff)-1, &ticket.from,
                           &ticket.protocol);
      buff[buflen]='\0';

      /*
       * evaluate the access lists (IP based filter)
       */
      access=accesslist_check(ticket.from);
      if (access == 0) {
         DEBUGC(DBCLASS_ACCESS,"access for this packet was denied");
         continue; /* there are no resources to free */
      }

      /*
       * integrity checks
       */
      sts=security_check_raw(buff, buflen);
      if (sts != STS_SUCCESS) {
         DEBUGC(DBCLASS_SIP,"security check (raw) failed");
         continue; /* there are no resources to free */
      }

      /*
       * init sip_msg
       */
      sts=osip_message_init(&ticket.sipmsg);
      ticket.sipmsg->message=NULL;
      if (sts != 0) {
         ERROR("osip_message_init() failed... this is not good");
         continue; /* skip, there are no resources to free */
      }

      /*
       * RFC 3261, Section 16.3 step 1
       * Proxy Behavior - Request Validation - Reasonable Syntax
       * (parse the received message)
       */
      sts=sip_message_parse(ticket.sipmsg, buff, buflen);
      if (sts != 0) {
         ERROR("sip_message_parse() failed... this is not good");
         DUMP_BUFFER(-1, buff, buflen);
         goto end_loop; /* skip and free resources */
      }

      /*
       * integrity checks - parsed buffer
       */
      sts=security_check_sip(&ticket);
      if (sts != STS_SUCCESS) {
         ERROR("security_check_sip() failed... this is not good");
         DUMP_BUFFER(-1, buff, buflen);
         goto end_loop; /* skip and free resources */
      }

      /*
       * RFC 3261, Section 16.3 step 2
       * Proxy Behavior - Request Validation - URI scheme
       * (check request URI and refuse with 416 if not understood)
       */
      /* NOT IMPLEMENTED */

      /*
       * RFC 3261, Section 16.3 step 3
       * Proxy Behavior - Request Validation - Max-Forwards check
       * (check Max-Forwards header and refuse with 483 if too many hops)
       */
      {
         osip_header_t *max_forwards;
         int forwards_count = DEFAULT_MAXFWD;

         osip_message_get_max_forwards(ticket.sipmsg, 0, &max_forwards);
         if (max_forwards && max_forwards->hvalue) {
            forwards_count = atoi(max_forwards->hvalue);
         }

         DEBUGC(DBCLASS_PROXY,"checking Max-Forwards (=%i)",forwards_count);
         if (forwards_count <= 0) {
            DEBUGC(DBCLASS_SIP, "Forward count reached 0 -> 483 response");
            sip_gen_response(&ticket, 483 /*Too many hops*/);
            goto end_loop; /* skip and free resources */
         }
      }

      /*
       * RFC 3261, Section 16.3 step 4
       * Proxy Behavior - Request Validation - Loop Detection check
       * (check for loop and return 482 if a loop is detected)
       */
      if (check_vialoop(&ticket) == STS_TRUE) {
         /* make sure we don't end up in endless loop when detecting
          * an loop in an "loop detected" message - brrr */
         if (MSG_IS_RESPONSE(ticket.sipmsg) && 
             MSG_TEST_CODE(ticket.sipmsg, 482)) {
            DEBUGC(DBCLASS_SIP,"loop in loop-response detected, ignoring");
         } else {
            DEBUGC(DBCLASS_SIP,"via loop detected, ignoring request");
            sip_gen_response(&ticket, 482 /*Loop detected*/);
         }
         goto end_loop; /* skip and free resources */
      }

      /*
       * RFC 3261, Section 16.3 step 5
       * Proxy Behavior - Request Validation - Proxy-Require check
       * (check Proxy-Require header and return 420 if unsupported option)
       */
      /* NOT IMPLEMENTED */

      /*
       * RFC 3261, Section 16.5
       * Proxy Behavior - Determining Request Targets
       */
      /* NOT IMPLEMENTED */

      DEBUGC(DBCLASS_SIP,"received SIP type %s:%s",
             (MSG_IS_REQUEST(ticket.sipmsg))? "REQ" : "RES",
             (MSG_IS_REQUEST(ticket.sipmsg) ?
                ((ticket.sipmsg->sip_method)?
                   ticket.sipmsg->sip_method : "NULL") :
                ((ticket.sipmsg->reason_phrase) ? 
                   ticket.sipmsg->reason_phrase : "NULL")));

      /*********************************
       * The message did pass all the
       * tests above and is now ready
       * to be proxied.
       * Before we do so, we apply some
       * additional preprocessing
       *********************************/
      /* Dial shortcuts */
      if (configuration.pi_shortdial) {
         sts = plugin_shortdial(&ticket);
         if (sts == STS_SIP_SENT) goto end_loop;
      }


      /*********************************
       * finally proxy the message.
       * This includes the masquerading
       * of the local UA and starting/
       * stopping the RTP proxy for this
       * call
       *********************************/

      /*
       * if a REQ REGISTER, check if it is directed to myself,
       * or am I just the outbound proxy but no registrar.
       * - If I'm the registrar, register & generate answer
       * - If I'm just the outbound proxy, register, rewrite & forward
       */
      if (MSG_IS_REGISTER(ticket.sipmsg) && 
          MSG_IS_REQUEST(ticket.sipmsg)) {
         if (access & ACCESSCTL_REG) {
            osip_uri_t *url;
            struct in_addr addr1, addr2, addr3;
            int dest_port;

            url = osip_message_get_uri(ticket.sipmsg);
            dest_port= (url->port)?atoi(url->port):SIP_PORT;

            if ( (get_ip_by_host(url->host, &addr1) == STS_SUCCESS) &&
                 (get_interface_ip(IF_INBOUND,&addr2) == STS_SUCCESS) &&
                 (get_interface_ip(IF_OUTBOUND,&addr3) == STS_SUCCESS)) {

               if ((configuration.sip_listen_port == dest_port) &&
                   ((memcmp(&addr1, &addr2, sizeof(addr1)) == 0) ||
                    (memcmp(&addr1, &addr3, sizeof(addr1)) == 0))) {
                  /* I'm the registrar, send response myself */
                  sts = register_client(&ticket, 0);
                  sts = register_response(&ticket, sts);
               } else {
                  /* I'm just the outbound proxy */
                  DEBUGC(DBCLASS_SIP,"proxying REGISTER request to:%s",
                         url->host);
                  sts = register_client(&ticket, 1);
                  if (sts == STS_SUCCESS) {
                     sts = proxy_request(&ticket);
                  }
               }
            } else {
               sip_gen_response(&ticket, 408 /*request timeout*/);
            }
         } else {
            WARN("non-authorized registration attempt from %s",
                 utils_inet_ntoa(ticket.from.sin_addr));
         }

      /*
       * check if outbound interface is UP.
       * If not, send back error to UA and
       * skip any proxying attempt
       */
      } else if (get_interface_ip(IF_OUTBOUND,NULL) !=
                 STS_SUCCESS) {
         DEBUGC(DBCLASS_SIP, "got a %s to proxy, but outbound interface "
                "is down", (MSG_IS_REQUEST(ticket.sipmsg))? "REQ" : "RES");

         if (MSG_IS_REQUEST(ticket.sipmsg))
            sip_gen_response(&ticket, 408 /*request timeout*/);
      
      /*
       * MSG is a request, add current via entry,
       * do a lookup in the URLMAP table and
       * send to the final destination
       */
      } else if (MSG_IS_REQUEST(ticket.sipmsg)) {
         if (access & ACCESSCTL_SIP) {
            sts = proxy_request(&ticket);
         } else {
            INFO("non-authorized request received from %s",
                 utils_inet_ntoa(ticket.from.sin_addr));
         }

      /*
       * MSG is a response, remove current via and
       * send to the next VIA in chain
       */
      } else if (MSG_IS_RESPONSE(ticket.sipmsg)) {
         if (access & ACCESSCTL_SIP) {
            sts = proxy_response(&ticket);
         } else {
            INFO("non-authorized response received from %s",
                 utils_inet_ntoa(ticket.from.sin_addr));
         }
         
      /*
       * unsupported message
       */
      } else {
         ERROR("received unsupported SIP type %s %s",
               (MSG_IS_REQUEST(ticket.sipmsg))? "REQ" : "RES",
               ticket.sipmsg->sip_method);
      }

      /*********************************
       * Done with proxying. Message
       * has been sent to its destination.
       *********************************/
/*
 * free the SIP message buffers
 */
      end_loop:
      osip_message_free(ticket.sipmsg);

   } /* while TRUE */
   exit_prg:

   /* save current known SIP registrations */
   register_save();
   INFO("properly terminating siproxd");

   /* remove PID file */
   if (pidfilename) {
      DEBUGC(DBCLASS_CONFIG,"deleting PID file [%s]", pidfilename);
      sts=unlink(pidfilename);
      if (sts != 0) {
         WARN("couldn't delete old PID file: %s", strerror(errno));
      }
   }

   /* END */
   return 0;
} /* main */

/*
 * Signal handler
 *
 * this one is called asynchronously whevener a registered
 * signal is applied. Just set a flag and don't do any funny
 * things here.
 */
static void sighandler(int sig) {
   if (sig==SIGTERM) exit_program=1;
   if (sig==SIGINT)  exit_program=1;
   if (sig==SIGUSR2) dmalloc_dump=1;
   return;
}
static ssize_t rmnet_ctl_read(struct file *file, char __user *buf, size_t count,
		loff_t *ppos)
{
	int				retval = 0;
	int				bytes_to_read;
	unsigned int			hdr_len = 0;
	struct rmnet_ctrl_dev		*dev;
	struct ctrl_pkt_list_elem	*list_elem = NULL;
	unsigned long			flags;

	dev = file->private_data;
	if (!dev)
		return -ENODEV;

	DBG("%s: Read from %s\n", __func__, dev->name);

ctrl_read:
	if (!test_bit(RMNET_CTRL_DEV_READY, &dev->status)) {
		dev_err(dev->devicep, "%s: Device not connected\n",
			__func__);
		return -ENETRESET;
	}
	spin_lock_irqsave(&dev->rx_lock, flags);
	if (list_empty(&dev->rx_list)) {
		spin_unlock_irqrestore(&dev->rx_lock, flags);

		retval = wait_event_interruptible(dev->read_wait_queue,
				!list_empty(&dev->rx_list) ||
				!test_bit(RMNET_CTRL_DEV_READY, &dev->status));
		if (retval < 0)
			return retval;

		goto ctrl_read;
	}

	list_elem = list_first_entry(&dev->rx_list,
				     struct ctrl_pkt_list_elem, list);
	bytes_to_read = (uint32_t)(list_elem->cpkt.data_size);
	if (bytes_to_read > count) {
		spin_unlock_irqrestore(&dev->rx_lock, flags);
		dev_err(dev->devicep, "%s: Packet size %d > buf size %d\n",
			__func__, bytes_to_read, count);
		return -ENOMEM;
	}
	spin_unlock_irqrestore(&dev->rx_lock, flags);

	if (test_bit(RMNET_CTRL_DEV_MUX_EN, &dev->status))
		hdr_len = sizeof(struct mux_hdr);

	if (copy_to_user(buf, list_elem->cpkt.data + hdr_len, bytes_to_read)) {
			dev_err(dev->devicep,
				"%s: copy_to_user failed for %s\n",
				__func__, dev->name);
		return -EFAULT;
	}
	spin_lock_irqsave(&dev->rx_lock, flags);
	list_del(&list_elem->list);
	spin_unlock_irqrestore(&dev->rx_lock, flags);

	kfree(list_elem->cpkt.data);
	kfree(list_elem);
	DBG("%s: Returning %d bytes to %s\n", __func__, bytes_to_read,
			dev->name);
	DUMP_BUFFER("Read: ", bytes_to_read, buf);

	return bytes_to_read;
}
acpi_status
acpi_tb_convert_table_fadt (void)
{

#ifdef _IA64
	fadt_descriptor_rev071 *FADT71;
	u8                      pm1_address_space;
	u8                      pm2_address_space;
	u8                      pm_timer_address_space;
	u8                      gpe0address_space;
	u8                      gpe1_address_space;
#else
	fadt_descriptor_rev1   *FADT1;
#endif

	fadt_descriptor_rev2   *FADT2;
	acpi_table_desc        *table_desc;


	FUNCTION_TRACE ("Tb_convert_table_fadt");


	/* Acpi_gbl_FADT is valid */
	/* Allocate and zero the 2.0 buffer */

	FADT2 = ACPI_MEM_CALLOCATE (sizeof (fadt_descriptor_rev2));
	if (FADT2 == NULL) {
		return_ACPI_STATUS (AE_NO_MEMORY);
	}


	/* The ACPI FADT revision number is FADT2_REVISION_ID=3 */
	/* So, if the current table revision is less than 3 it is type 1.0 or 0.71 */

	if (acpi_gbl_FADT->header.revision >= FADT2_REVISION_ID) {
		/* We have an ACPI 2.0 FADT but we must copy it to our local buffer */

		*FADT2 = *((fadt_descriptor_rev2*) acpi_gbl_FADT);

	}

	else {

#ifdef _IA64
		/*
		 * For the 64-bit case only, a revision ID less than V2.0 means the
		 * tables are the 0.71 extensions
		 */

		/* The BIOS stored FADT should agree with Revision 0.71 */

		FADT71 = (fadt_descriptor_rev071 *) acpi_gbl_FADT;

		/* Copy the table header*/

		FADT2->header       = FADT71->header;

		/* Copy the common fields */

		FADT2->sci_int      = FADT71->sci_int;
		FADT2->acpi_enable  = FADT71->acpi_enable;
		FADT2->acpi_disable = FADT71->acpi_disable;
		FADT2->S4bios_req   = FADT71->S4bios_req;
		FADT2->plvl2_lat    = FADT71->plvl2_lat;
		FADT2->plvl3_lat    = FADT71->plvl3_lat;
		FADT2->day_alrm     = FADT71->day_alrm;
		FADT2->mon_alrm     = FADT71->mon_alrm;
		FADT2->century      = FADT71->century;
		FADT2->gpe1_base    = FADT71->gpe1_base;

		/*
		 * We still use the block length registers even though
		 * the GAS structure should obsolete them.  This is because
		 * these registers are byte lengths versus the GAS which
		 * contains a bit width
		 */
		FADT2->pm1_evt_len  = FADT71->pm1_evt_len;
		FADT2->pm1_cnt_len  = FADT71->pm1_cnt_len;
		FADT2->pm2_cnt_len  = FADT71->pm2_cnt_len;
		FADT2->pm_tm_len    = FADT71->pm_tm_len;
		FADT2->gpe0blk_len  = FADT71->gpe0blk_len;
		FADT2->gpe1_blk_len = FADT71->gpe1_blk_len;
		FADT2->gpe1_base    = FADT71->gpe1_base;

		/* Copy the existing 0.71 flags to 2.0. The other bits are zero.*/

		FADT2->wb_invd      = FADT71->flush_cash;
		FADT2->proc_c1      = FADT71->proc_c1;
		FADT2->plvl2_up     = FADT71->plvl2_up;
		FADT2->pwr_button   = FADT71->pwr_button;
		FADT2->sleep_button = FADT71->sleep_button;
		FADT2->fixed_rTC    = FADT71->fixed_rTC;
		FADT2->rtcs4        = FADT71->rtcs4;
		FADT2->tmr_val_ext  = FADT71->tmr_val_ext;
		FADT2->dock_cap     = FADT71->dock_cap;


		/* We should not use these next two addresses */
		/* Since our buffer is pre-zeroed nothing to do for */
		/* the next three data items in the structure */
		/* FADT2->Firmware_ctrl = 0; */
		/* FADT2->Dsdt = 0; */

		/* System Interrupt Model isn't used in ACPI 2.0*/
		/* FADT2->Reserved1 = 0; */

		/* This field is set by the OEM to convey the preferred */
		/* power management profile to OSPM. It doesn't have any*/
		/* 0.71 equivalence.  Since we don't know what kind of  */
		/* 64-bit system this is, we will pick unspecified.     */

		FADT2->prefer_PM_profile = PM_UNSPECIFIED;


		/* Port address of SMI command port */
		/* We shouldn't use this port because IA64 doesn't */
		/* have or use SMI.  It has PMI. */

		FADT2->smi_cmd      = (u32)(FADT71->smi_cmd & 0xFFFFFFFF);


		/* processor performance state control*/
		/* The value OSPM writes to the SMI_CMD register to assume */
		/* processor performance state control responsibility. */
		/* There isn't any equivalence in 0.71 */
		/* Again this should be meaningless for IA64 */
		/* FADT2->Pstate_cnt = 0; */

		/* The 32-bit Power management and GPE registers are */
		/* not valid in IA-64 and we are not going to use them */
		/* so leaving them pre-zeroed. */

		/* Support for the _CST object and C States change notification.*/
		/* This data item hasn't any 0.71 equivalence so leaving it zero.*/
		/* FADT2->Cst_cnt = 0; */

		/* number of flush strides that need to be read */
		/* No 0.71 equivalence. Leave pre-zeroed. */
		/* FADT2->Flush_size = 0; */

		/* Processor's memory cache line width, in bytes */
		/* No 0.71 equivalence. Leave pre-zeroed. */
		/* FADT2->Flush_stride = 0; */

		/* Processor's duty cycle index in processor's P_CNT reg*/
		/* No 0.71 equivalence. Leave pre-zeroed. */
		/* FADT2->Duty_offset = 0; */

		/* Processor's duty cycle value bit width in P_CNT register.*/
		/* No 0.71 equivalence. Leave pre-zeroed. */
		/* FADT2->Duty_width = 0; */


		/* Since there isn't any equivalence in 0.71 */
		/* and since Big_sur had to support legacy */

		FADT2->iapc_boot_arch = BAF_LEGACY_DEVICES;

		/* Copy to ACPI 2.0 64-BIT Extended Addresses */

		FADT2->Xfirmware_ctrl = FADT71->firmware_ctrl;
		FADT2->Xdsdt         = FADT71->dsdt;


		/* Extract the address space IDs */

		pm1_address_space   = (u8)((FADT71->address_space & PM1_BLK_ADDRESS_SPACE)    >> 1);
		pm2_address_space   = (u8)((FADT71->address_space & PM2_CNT_BLK_ADDRESS_SPACE) >> 2);
		pm_timer_address_space = (u8)((FADT71->address_space & PM_TMR_BLK_ADDRESS_SPACE) >> 3);
		gpe0address_space   = (u8)((FADT71->address_space & GPE0_BLK_ADDRESS_SPACE)   >> 4);
		gpe1_address_space  = (u8)((FADT71->address_space & GPE1_BLK_ADDRESS_SPACE)   >> 5);

		/*
		 * Convert the 0.71 (non-GAS style) Block addresses to V2.0 GAS structures,
		 * in this order:
		 *
		 * PM 1_a Events
		 * PM 1_b Events
		 * PM 1_a Control
		 * PM 1_b Control
		 * PM 2 Control
		 * PM Timer Control
		 * GPE Block 0
		 * GPE Block 1
		 */

		ASL_BUILD_GAS_FROM_ENTRY (FADT2->Xpm1a_evt_blk, FADT71->pm1_evt_len, FADT71->pm1a_evt_blk, pm1_address_space);
		ASL_BUILD_GAS_FROM_ENTRY (FADT2->Xpm1b_evt_blk, FADT71->pm1_evt_len, FADT71->pm1b_evt_blk, pm1_address_space);
		ASL_BUILD_GAS_FROM_ENTRY (FADT2->Xpm1a_cnt_blk, FADT71->pm1_cnt_len, FADT71->pm1a_cnt_blk, pm1_address_space);
		ASL_BUILD_GAS_FROM_ENTRY (FADT2->Xpm1b_cnt_blk, FADT71->pm1_cnt_len, FADT71->pm1b_cnt_blk, pm1_address_space);
		ASL_BUILD_GAS_FROM_ENTRY (FADT2->Xpm2_cnt_blk, FADT71->pm2_cnt_len, FADT71->pm2_cnt_blk, pm2_address_space);
		ASL_BUILD_GAS_FROM_ENTRY (FADT2->Xpm_tmr_blk, FADT71->pm_tm_len,  FADT71->pm_tmr_blk, pm_timer_address_space);
		ASL_BUILD_GAS_FROM_ENTRY (FADT2->Xgpe0blk,    FADT71->gpe0blk_len, FADT71->gpe0blk,   gpe0address_space);
		ASL_BUILD_GAS_FROM_ENTRY (FADT2->Xgpe1_blk,   FADT71->gpe1_blk_len, FADT71->gpe1_blk, gpe1_address_space);

#else

		/* ACPI 1.0 FACS */


		/* The BIOS stored FADT should agree with Revision 1.0 */

		FADT1 = (fadt_descriptor_rev1*) acpi_gbl_FADT;

		/*
		 * Copy the table header and the common part of the tables
		 * The 2.0 table is an extension of the 1.0 table, so the
		 * entire 1.0 table can be copied first, then expand some
		 * fields to 64 bits.
		 */
		MEMCPY (FADT2, FADT1, sizeof (fadt_descriptor_rev1));


		/* Convert table pointers to 64-bit fields */

		ACPI_STORE_ADDRESS (FADT2->Xfirmware_ctrl, FADT1->firmware_ctrl);
		ACPI_STORE_ADDRESS (FADT2->Xdsdt, FADT1->dsdt);

		/* System Interrupt Model isn't used in ACPI 2.0*/
		/* FADT2->Reserved1 = 0; */

		/* This field is set by the OEM to convey the preferred */
		/* power management profile to OSPM. It doesn't have any*/
		/* 1.0 equivalence.  Since we don't know what kind of   */
		/* 32-bit system this is, we will pick unspecified.     */

		FADT2->prefer_PM_profile = PM_UNSPECIFIED;


		/* Processor Performance State Control. This is the value  */
		/* OSPM writes to the SMI_CMD register to assume processor */
		/* performance state control responsibility. There isn't   */
		/* any equivalence in 1.0.  So leave it zeroed.            */

		FADT2->pstate_cnt = 0;


		/* Support for the _CST object and C States change notification.*/
		/* This data item hasn't any 1.0 equivalence so leaving it zero.*/

		FADT2->cst_cnt = 0;


		/* Since there isn't any equivalence in 1.0 and since it   */
		/* is highly likely that a 1.0 system has legacy  support. */

		FADT2->iapc_boot_arch = BAF_LEGACY_DEVICES;


		/*
		 * Convert the V1.0 Block addresses to V2.0 GAS structures
		 * in this order:
		 *
		 * PM 1_a Events
		 * PM 1_b Events
		 * PM 1_a Control
		 * PM 1_b Control
		 * PM 2 Control
		 * PM Timer Control
		 * GPE Block 0
		 * GPE Block 1
		 */

		ASL_BUILD_GAS_FROM_V1_ENTRY (FADT2->Xpm1a_evt_blk, FADT1->pm1_evt_len, FADT1->pm1a_evt_blk);
		ASL_BUILD_GAS_FROM_V1_ENTRY (FADT2->Xpm1b_evt_blk, FADT1->pm1_evt_len, FADT1->pm1b_evt_blk);
		ASL_BUILD_GAS_FROM_V1_ENTRY (FADT2->Xpm1a_cnt_blk, FADT1->pm1_cnt_len, FADT1->pm1a_cnt_blk);
		ASL_BUILD_GAS_FROM_V1_ENTRY (FADT2->Xpm1b_cnt_blk, FADT1->pm1_cnt_len, FADT1->pm1b_cnt_blk);
		ASL_BUILD_GAS_FROM_V1_ENTRY (FADT2->Xpm2_cnt_blk, FADT1->pm2_cnt_len, FADT1->pm2_cnt_blk);
		ASL_BUILD_GAS_FROM_V1_ENTRY (FADT2->Xpm_tmr_blk, FADT1->pm_tm_len,  FADT1->pm_tmr_blk);
		ASL_BUILD_GAS_FROM_V1_ENTRY (FADT2->Xgpe0blk,    FADT1->gpe0blk_len, FADT1->gpe0blk);
		ASL_BUILD_GAS_FROM_V1_ENTRY (FADT2->Xgpe1_blk,   FADT1->gpe1_blk_len, FADT1->gpe1_blk);
#endif
	}


	/*
	 * Global FADT pointer will point to the common V2.0 FADT
	 */
	acpi_gbl_FADT = FADT2;
	acpi_gbl_FADT->header.length = sizeof (FADT_DESCRIPTOR);


	/* Free the original table */

	table_desc = &acpi_gbl_acpi_tables[ACPI_TABLE_FADT];
	acpi_tb_delete_single_table (table_desc);


	/* Install the new table */

	table_desc->pointer = (acpi_table_header *) acpi_gbl_FADT;
	table_desc->base_pointer = acpi_gbl_FADT;
	table_desc->allocation = ACPI_MEM_ALLOCATED;
	table_desc->length = sizeof (fadt_descriptor_rev2);


	/* Dump the entire FADT */

	ACPI_DEBUG_PRINT ((ACPI_DB_TABLES,
		"Hex dump of common internal FADT, size %d (%X)\n",
		acpi_gbl_FADT->header.length, acpi_gbl_FADT->header.length));
	DUMP_BUFFER ((u8 *) (acpi_gbl_FADT), acpi_gbl_FADT->header.length);


	return_ACPI_STATUS (AE_OK);
}
Example #11
0
ACPI_STATUS
AcpiPsParseLoop (
    ACPI_WALK_STATE         *WalkState)
{
    ACPI_STATUS             Status = AE_OK;
    ACPI_PARSE_OBJECT       *Op = NULL;     /* current op */
    const ACPI_OPCODE_INFO  *OpInfo;
    ACPI_PARSE_OBJECT       *Arg = NULL;
    ACPI_PARSE2_OBJECT      *DeferredOp;
    UINT32                  ArgCount;       /* push for fixed or var args */
    UINT32                  ArgTypes = 0;
    UINT32                  AmlOffset;
    UINT16                  Opcode;
    ACPI_PARSE_OBJECT       PreOp;
    ACPI_PARSE_STATE        *ParserState;
    UINT8                   *AmlOpStart;


    FUNCTION_TRACE_PTR ("PsParseLoop", WalkState);


    ParserState = WalkState->ParserState;

#ifndef PARSER_ONLY
    if (WalkState->WalkType & WALK_METHOD_RESTART)
    {
        /* We are restarting a preempted control method */

        if (AcpiPsHasCompletedScope (ParserState))
        {
            /*
             * We must check if a predicate to an IF or WHILE statement
             * was just completed
             */
            if ((ParserState->Scope->ParseScope.Op) &&
                ((ParserState->Scope->ParseScope.Op->Opcode == AML_IF_OP) ||
                (ParserState->Scope->ParseScope.Op->Opcode == AML_WHILE_OP)) &&
                (WalkState->ControlState) &&
                (WalkState->ControlState->Common.State ==
                    CONTROL_PREDICATE_EXECUTING))
            {

                /*
                 * A predicate was just completed, get the value of the
                 * predicate and branch based on that value
                 */
                Status = AcpiDsGetPredicateValue (WalkState, NULL, TRUE);
                if (ACPI_FAILURE (Status) &&
                    ((Status & AE_CODE_MASK) != AE_CODE_CONTROL))
                {
                    if (Status == AE_AML_NO_RETURN_VALUE)
                    {
                        ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
                            "Invoked method did not return a value, %s\n",
                            AcpiFormatException (Status)));

                    }
                    ACPI_DEBUG_PRINT ((ACPI_DB_ERROR, "GetPredicate Failed, %s\n",
                        AcpiFormatException (Status)));
                    return_ACPI_STATUS (Status);
                }

                Status = AcpiPsNextParseState (WalkState, Op, Status);
            }

            AcpiPsPopScope (ParserState, &Op, &ArgTypes, &ArgCount);
            ACPI_DEBUG_PRINT ((ACPI_DB_PARSE, "Popped scope, Op=%p\n", Op));
        }

        else if (WalkState->PrevOp)
        {
            /* We were in the middle of an op */

            Op = WalkState->PrevOp;
            ArgTypes = WalkState->PrevArgTypes;
        }
    }
#endif

    /*
     * Iterative parsing loop, while there is more aml to process:
     */
    while ((ParserState->Aml < ParserState->AmlEnd) || (Op))
    {
        if (!Op)
        {
            /* Get the next opcode from the AML stream */

            AmlOpStart = ParserState->Aml;
            AmlOffset  = ParserState->Aml - ParserState->AmlStart;
            Opcode     = AcpiPsPeekOpcode (ParserState);

            /*
             * First cut to determine what we have found:
             * 1) A valid AML opcode
             * 2) A name string
             * 3) An unknown/invalid opcode
             */
            OpInfo = AcpiPsGetOpcodeInfo (Opcode);
            switch (ACPI_GET_OP_TYPE (OpInfo))
            {
            case ACPI_OP_TYPE_OPCODE:

                /* Found opcode info, this is a normal opcode */

                ParserState->Aml += AcpiPsGetOpcodeSize (Opcode);
                ArgTypes = OpInfo->ParseArgs;
                break;

            case ACPI_OP_TYPE_ASCII:
            case ACPI_OP_TYPE_PREFIX:
                /*
                 * Starts with a valid prefix or ASCII char, this is a name
                 * string.  Convert the bare name string to a namepath.
                 */
                Opcode = AML_INT_NAMEPATH_OP;
                ArgTypes = ARGP_NAMESTRING;
                break;

            case ACPI_OP_TYPE_UNKNOWN:

                /* The opcode is unrecognized.  Just skip unknown opcodes */

                ACPI_DEBUG_PRINT ((ACPI_DB_ERROR,
                    "Found unknown opcode %lX at AML offset %X, ignoring\n",
                    Opcode, AmlOffset));

                DUMP_BUFFER (ParserState->Aml, 128);

                /* Assume one-byte bad opcode */

                ParserState->Aml++;
                continue;
            }


            /* Create Op structure and append to parent's argument list */

            if (OpInfo->Flags & AML_NAMED)
            {
                PreOp.Value.Arg = NULL;
                PreOp.Opcode = Opcode;

                while (GET_CURRENT_ARG_TYPE (ArgTypes) != ARGP_NAME)
                {
                    Arg = AcpiPsGetNextArg (ParserState,
                                            GET_CURRENT_ARG_TYPE (ArgTypes),
                                            &ArgCount);
                    AcpiPsAppendArg (&PreOp, Arg);
                    INCREMENT_ARG_LIST (ArgTypes);
                }


                /* We know that this arg is a name, move to next arg */

                INCREMENT_ARG_LIST (ArgTypes);

                if (WalkState->DescendingCallback != NULL)
                {
                    /*
                     * Find the object.  This will either insert the object into
                     * the namespace or simply look it up
                     */
                    Status = WalkState->DescendingCallback (Opcode, NULL, WalkState, &Op);
                    if (Op == NULL)
                    {
                        continue;
                    }
                    Status = AcpiPsNextParseState (WalkState, Op, Status);
                    if (Status == AE_CTRL_PENDING)
                    {
                        Status = AE_OK;
                        goto CloseThisOp;
                    }

                    if (ACPI_FAILURE (Status))
                    {
                        goto CloseThisOp;
                    }
                }

                AcpiPsAppendArg (Op, PreOp.Value.Arg);
                AcpiGbl_Depth++;


                if (Op->Opcode == AML_REGION_OP)
                {
                    DeferredOp = (ACPI_PARSE2_OBJECT *) Op;

                    /*
                     * Defer final parsing of an OperationRegion body,
                     * because we don't have enough info in the first pass
                     * to parse it correctly (i.e., there may be method
                     * calls within the TermArg elements of the body.
                     *
                     * However, we must continue parsing because
                     * the opregion is not a standalone package --
                     * we don't know where the end is at this point.
                     *
                     * (Length is unknown until parse of the body complete)
                     */
                    DeferredOp->Data    = AmlOpStart;
                    DeferredOp->Length  = 0;
                }
            }


            else
            {
                /* Not a named opcode, just allocate Op and append to parent */

                OpInfo = AcpiPsGetOpcodeInfo (Opcode);
                Op = AcpiPsAllocOp (Opcode);
                if (!Op)
                {
                    return_ACPI_STATUS (AE_NO_MEMORY);
                }


                if (OpInfo->Flags & AML_CREATE)
                {
                    /*
                     * Backup to beginning of CreateXXXfield declaration
                     * BodyLength is unknown until we parse the body
                     */
                    DeferredOp = (ACPI_PARSE2_OBJECT *) Op;

                    DeferredOp->Data    = AmlOpStart;
                    DeferredOp->Length  = 0;
                }

                AcpiPsAppendArg (AcpiPsGetParentScope (ParserState), Op);

                if ((WalkState->DescendingCallback != NULL))
                {
                    /*
                     * Find the object.  This will either insert the object into
                     * the namespace or simply look it up
                     */
                    Status = WalkState->DescendingCallback (Opcode, Op, WalkState, &Op);
                    Status = AcpiPsNextParseState (WalkState, Op, Status);
                    if (Status == AE_CTRL_PENDING)
                    {
                        Status = AE_OK;
                        goto CloseThisOp;
                    }

                    if (ACPI_FAILURE (Status))
                    {
                        goto CloseThisOp;
                    }
                }
            }

            Op->AmlOffset = AmlOffset;

            if (OpInfo)
            {
                ACPI_DEBUG_PRINT ((ACPI_DB_PARSE,
                    "Op=%p Opcode=%4.4lX Aml %p Oft=%5.5lX\n",
                     Op, Op->Opcode, ParserState->Aml, Op->AmlOffset));
            }
        }


        /* Start ArgCount at zero because we don't know if there are any args yet */

        ArgCount  = 0;


        if (ArgTypes)   /* Are there any arguments that must be processed? */
        {
            /* get arguments */

            switch (Op->Opcode)
            {
            case AML_BYTE_OP:       /* AML_BYTEDATA_ARG */
            case AML_WORD_OP:       /* AML_WORDDATA_ARG */
            case AML_DWORD_OP:      /* AML_DWORDATA_ARG */
            case AML_QWORD_OP:      /* AML_QWORDATA_ARG */
            case AML_STRING_OP:     /* AML_ASCIICHARLIST_ARG */

                /* fill in constant or string argument directly */

                AcpiPsGetNextSimpleArg (ParserState,
                                        GET_CURRENT_ARG_TYPE (ArgTypes), Op);
                break;

            case AML_INT_NAMEPATH_OP:   /* AML_NAMESTRING_ARG */

                AcpiPsGetNextNamepath (ParserState, Op, &ArgCount, 1);
                ArgTypes = 0;
                break;


            default:

                /* Op is not a constant or string, append each argument */

                while (GET_CURRENT_ARG_TYPE (ArgTypes) && !ArgCount)
                {
                    AmlOffset = ParserState->Aml - ParserState->AmlStart;
                    Arg = AcpiPsGetNextArg (ParserState,
                                            GET_CURRENT_ARG_TYPE (ArgTypes),
                                            &ArgCount);
                    if (Arg)
                    {
                        Arg->AmlOffset = AmlOffset;
                        AcpiPsAppendArg (Op, Arg);
                    }

                    INCREMENT_ARG_LIST (ArgTypes);
                }


                /* For a method, save the length and address of the body */

                if (Op->Opcode == AML_METHOD_OP)
                {
                    DeferredOp = (ACPI_PARSE2_OBJECT *) Op;

                    /*
                     * Skip parsing of control method or opregion body,
                     * because we don't have enough info in the first pass
                     * to parse them correctly.
                     */
                    DeferredOp->Data    = ParserState->Aml;
                    DeferredOp->Length  = (UINT32) (ParserState->PkgEnd -
                                                    ParserState->Aml);

                    /*
                     * Skip body of method.  For OpRegions, we must continue
                     * parsing because the opregion is not a standalone
                     * package (We don't know where the end is).
                     */
                    ParserState->Aml    = ParserState->PkgEnd;
                    ArgCount            = 0;
                }

                break;
            }
        }


        /*
         * Zero ArgCount means that all arguments for this op have been processed
         */
        if (!ArgCount)
        {
            /* completed Op, prepare for next */

            OpInfo = AcpiPsGetOpcodeInfo (Op->Opcode);
            if (OpInfo->Flags & AML_NAMED)
            {
                if (AcpiGbl_Depth)
                {
                    AcpiGbl_Depth--;
                }

                if (Op->Opcode == AML_REGION_OP)
                {
                    DeferredOp = (ACPI_PARSE2_OBJECT *) Op;

                    /*
                     * Skip parsing of control method or opregion body,
                     * because we don't have enough info in the first pass
                     * to parse them correctly.
                     *
                     * Completed parsing an OpRegion declaration, we now
                     * know the length.
                     */
                    DeferredOp->Length = (UINT32) (ParserState->Aml -
                                                    DeferredOp->Data);
                }
            }

            if (OpInfo->Flags & AML_CREATE)
            {
                /*
                 * Backup to beginning of CreateXXXfield declaration (1 for
                 * Opcode)
                 *
                 * BodyLength is unknown until we parse the body
                 */
                DeferredOp = (ACPI_PARSE2_OBJECT *) Op;
                DeferredOp->Length = (UINT32) (ParserState->Aml -
                                               DeferredOp->Data);
            }

            /* This op complete, notify the dispatcher */

            if (WalkState->AscendingCallback != NULL)
            {
                Status = WalkState->AscendingCallback (WalkState, Op);
                Status = AcpiPsNextParseState (WalkState, Op, Status);
                if (Status == AE_CTRL_PENDING)
                {
                    Status = AE_OK;
                    goto CloseThisOp;
                }
            }


CloseThisOp:

            /*
             * Finished one argument of the containing scope
             */
            ParserState->Scope->ParseScope.ArgCount--;

            /* Close this Op (may result in parse subtree deletion) */

            if (AcpiPsCompleteThisOp (WalkState, Op))
            {
                Op = NULL;
            }


            switch (Status)
            {
            case AE_OK:
                break;


            case AE_CTRL_TRANSFER:

                /*
                 * We are about to transfer to a called method.
                 */
                WalkState->PrevOp = Op;
                WalkState->PrevArgTypes = ArgTypes;
                return_ACPI_STATUS (Status);
                break;


            case AE_CTRL_END:

                AcpiPsPopScope (ParserState, &Op, &ArgTypes, &ArgCount);

                Status = WalkState->AscendingCallback (WalkState, Op);
                Status = AcpiPsNextParseState (WalkState, Op, Status);

                AcpiPsCompleteThisOp (WalkState, Op);
                Op = NULL;
                Status = AE_OK;
                break;


            case AE_CTRL_TERMINATE:

                Status = AE_OK;

                /* Clean up */
                do
                {
                    if (Op)
                    {
                        AcpiPsCompleteThisOp (WalkState, Op);
                    }

                    AcpiPsPopScope (ParserState, &Op, &ArgTypes, &ArgCount);
                } while (Op);

                return_ACPI_STATUS (Status);
                break;


            default:  /* All other non-AE_OK status */

                if (Op == NULL)
                {
                    AcpiPsPopScope (ParserState, &Op, &ArgTypes, &ArgCount);
                }
                WalkState->PrevOp = Op;
                WalkState->PrevArgTypes = ArgTypes;

                /*
                 * TEMP:
                 */

                return_ACPI_STATUS (Status);
                break;
            }

            /* This scope complete? */

            if (AcpiPsHasCompletedScope (ParserState))
            {
                AcpiPsPopScope (ParserState, &Op, &ArgTypes, &ArgCount);
                ACPI_DEBUG_PRINT ((ACPI_DB_PARSE, "Popped scope, Op=%p\n", Op));
            }

            else
            {
                Op = NULL;
            }

        }


        /* ArgCount is non-zero */

        else
        {
            /* complex argument, push Op and prepare for argument */

            AcpiPsPushScope (ParserState, Op, ArgTypes, ArgCount);
            Op = NULL;
        }

    } /* while ParserState->Aml */


    /*
     * Complete the last Op (if not completed), and clear the scope stack.
     * It is easily possible to end an AML "package" with an unbounded number
     * of open scopes (such as when several AML blocks are closed with
     * sequential closing braces).  We want to terminate each one cleanly.
     */
    ACPI_DEBUG_PRINT ((ACPI_DB_PARSE, "Package complete at Op %p\n", Op));
    do
    {
        if (Op)
        {
            if (WalkState->AscendingCallback != NULL)
            {
                Status = WalkState->AscendingCallback (WalkState, Op);
                Status = AcpiPsNextParseState (WalkState, Op, Status);
                if (Status == AE_CTRL_PENDING)
                {
                    Status = AE_OK;
                    goto CloseThisOp;
                }

                if (Status == AE_CTRL_TERMINATE)
                {
                    Status = AE_OK;

                    /* Clean up */
                    do
                    {
                        if (Op)
                        {
                            AcpiPsCompleteThisOp (WalkState, Op);
                        }

                        AcpiPsPopScope (ParserState, &Op, &ArgTypes, &ArgCount);

                    } while (Op);

                    return_ACPI_STATUS (Status);
                }

                else if (ACPI_FAILURE (Status))
                {
                    AcpiPsCompleteThisOp (WalkState, Op);
                    return_ACPI_STATUS (Status);
                }
            }

            AcpiPsCompleteThisOp (WalkState, Op);
        }

        AcpiPsPopScope (ParserState, &Op, &ArgTypes, &ArgCount);

    } while (Op);

    return_ACPI_STATUS (Status);
}
/*
 * Processing.
 * 
 */
int  PLUGIN_PROCESS(int stage, sip_ticket_t *ticket){
   /* stage contains the PLUGIN_* value - the stage of SIP processing. */
   int sts;
   char *buff;
   size_t buflen;
   osip_body_t *body;
   sdp_message_t  *sdp;
   int content_length;
   osip_content_type_t *content_type;
   char clen[8]; /* content length: probably never more than 7 digits !*/

   //
   // check that we have the expected payload "application/sdp"
   //

   // get content length
   content_length=0;
   if (ticket->sipmsg && ticket->sipmsg->content_length 
       && ticket->sipmsg->content_length->value) {
      sts=sscanf(ticket->sipmsg->content_length->value, "%i", &content_length);
   }

   // check if we have a content type defined and that payload length >0
   content_type=osip_message_get_content_type(ticket->sipmsg);
   if ((content_length == 0) || (content_type == NULL) 
       || (content_type->type == NULL) || (content_type->subtype == NULL)) {
      DEBUGC(DBCLASS_PLUGIN, "%s: no content", name);
      return STS_SUCCESS;
   }

   // check content type: must be "application/sdp"
   if ((strncmp(content_type->type, "application", sizeof("application")) != 0)
       || (strncmp(content_type->subtype, "sdp", sizeof("sdp")) != 0)) {
      DEBUGC(DBCLASS_PLUGIN, "%s: unsupported content-type %s/%s", name,
             content_type->type, content_type->subtype);
      return STS_SUCCESS;
   }

   DEBUGC(DBCLASS_PLUGIN, "%s: content-type %s/%s, size=%i", name, 
          content_type->type, content_type->subtype, content_length);

   //
   // parse the payload
   //

   // get a pointer to the payload of the SIP packet
   sts = osip_message_get_body(ticket->sipmsg, 0, &body);
   if (sts != 0) {
      DEBUGC(DBCLASS_PLUGIN, "%s: no body found in message", name);
      return STS_SUCCESS;
   }
   // dump it into a buffer
   sts = sip_body_to_str(body, &buff, &buflen);
   if (sts != 0) {
      WARN("%s: unable to sip_body_to_str", name);
      return STS_SUCCESS;
   }
   // and parse it into an SDP structure
   sts = sdp_message_init(&sdp);
   sts = sdp_message_parse (sdp, buff);
   if (sts != 0) {
      WARN("%s: unable to sdp_message_parse() body", name);
      DUMP_BUFFER(-1, buff, buflen);
      osip_free(buff);
      buff=NULL;
      sdp_message_free(sdp);
      return STS_SUCCESS;
   }
   osip_free(buff);
   buff=NULL;

   //
   // now do the codec filtering magic...
   sdp_filter_codec(sdp);

   //
   // replace the original payload with the new modified payload
   //
   
   // remove old body from SIP packet
   sts = osip_list_remove(&(ticket->sipmsg->bodies), 0);
   osip_body_free(body);
   body=NULL;

   // dump new body to buffer
   sdp_message_to_str(sdp, &buff);
   buflen=strlen(buff);

   // free sdp structure (no longer needed)
   sdp_message_free(sdp);
   sdp=NULL;

   // put new body into SIP message
   sts=sip_message_set_body(ticket->sipmsg, buff, buflen);
   if (sts != 0) {
      ERROR("%s: unable to sip_message_set_body body", name);
      DUMP_BUFFER(-1, buff, buflen);
      buflen=0;
   }
   // free buffer
   osip_free(buff);
   buff=NULL;

   //
   // set new content length
   //

   // remove old content leght field
   osip_content_length_free(ticket->sipmsg->content_length);
   ticket->sipmsg->content_length=NULL;

   // set new content length
   sprintf(clen,"%ld",(long)buflen);
   sts = osip_message_set_content_length(ticket->sipmsg, clen);

   return STS_SUCCESS;
}
Example #13
0
/*
 * sends an UDP datagram to the specified destination
 *
 * RETURNS
 *	STS_SUCCESS on success
 *	STS_FAILURE on error
 *  函数修改说明:
 *      修改人:    l67187
 *      修改目的:  解决代理和绑定时没有默认路由,sip alg无法工作的问题
 *      修改方案:  在报文发送时,bind上网关发送侧的ip地址,使用网关源地址路由
 *      具体修改:  原alg  使用  初始化时创建的 sip_udp_socket,绑定了空地址
 *                 无法再次绑定,修改后,在该函数中不在使用  sip_udp_socket发送报文
 *                 而是重新创建一个socket发送,之后就关闭释放资源
 */
int sipsock_send(struct in_addr addr, int port, int protocol,
                 char *buffer, int size) {
   
   struct sockaddr_in dst_addr;
   struct sockaddr_in stLocalAddr;
   int sock;
   int sts = -1;
   
   /* first time: allocate a socket for sending 
   if (sip_udp_socket == 0) {
      ERROR("SIP socket not allocated");
      return STS_FAILURE;
   }
*/
   if (buffer == NULL) {
      ERROR("sipsock_send got NULL buffer");
      return STS_FAILURE;
   }

   if (protocol != PROTO_UDP) {
      ERROR("sipsock_send: only UDP supported by now");
      return STS_FAILURE;
   }

    if (1 == g_lsockFlg)
    {

        
        dst_addr.sin_family = AF_INET;
        memcpy(&dst_addr.sin_addr.s_addr, &addr, sizeof(struct in_addr));
        dst_addr.sin_port= htons(port);

        if ((1 == IpisInNet(utils_inet_ntoa(addr), g_acBrIpAddr, g_acBrMask))
        || (1 == IpisInNet(utils_inet_ntoa(addr), g_acPPPoEIpAddr, g_acPPPoEMask)))
        {
            
            sts = sendto(sip_udp_socket, buffer, size, 0,
                 (const struct sockaddr *)&dst_addr,
                 (socklen_t)sizeof(dst_addr));
        }
        else  /* wan 侧 */
        {
            // TODO: 这里需要优化,目前PPPoE代理的时候没有默认路由
            // 因此需要进行判断,如果没有默认路由那么就需要使用使用sip_udp_wan_socket
            // 发包,否则一直使用 sip_udp_socket 发包
            // if (没有默认路由)
            if (0 != sip_udp_wan_socket)
            {

                sts = sendto(sip_udp_wan_socket, buffer, size, 0,
                     (const struct sockaddr *)&dst_addr,
                     (socklen_t)sizeof(dst_addr));
            }
            else if (0 == sip_udp_wan_socket)
            {
                sts = sendto(sip_udp_socket, buffer, size, 0,
                     (const struct sockaddr *)&dst_addr,
                     (socklen_t)sizeof(dst_addr));
            }
            else
            {
                ERROR("no proper socket fd to send out");
            }
        }
        
        if (sts == -1) {
           if (errno != ECONNREFUSED) {
              ERROR("sendto() [%s:%i size=%i] call failed: %s",
                    utils_inet_ntoa(addr),
                    port, size, strerror(errno));
              return STS_FAILURE;
           }
           DEBUGC(DBCLASS_BABBLE,"sendto() [%s:%i] call failed: %s",
                  utils_inet_ntoa(addr), port, strerror(errno));
        }
    }
    else
    {
   sock=socket (PF_INET, SOCK_DGRAM, IPPROTO_UDP);
   if (sock < 0) {
      printsip("Sip: socket() call failed: %s",strerror(errno));
      return STS_FAILURE;
   }

   dst_addr.sin_family = AF_INET;
   memcpy(&dst_addr.sin_addr.s_addr, &addr, sizeof(struct in_addr));
   dst_addr.sin_port= htons(port);

   DEBUGC(DBCLASS_NET,"send UDP packet to %s: %i", utils_inet_ntoa(addr),port);
   
   printsip("Sip:send UDP packet to %s: %i\r\n", utils_inet_ntoa(addr),port);
   DUMP_BUFFER(DBCLASS_NETTRAF, buffer, size);


    /* 本地发送源 */
    bzero(&stLocalAddr, 0);
    /* 目的ip为LAN侧ip */
    if ((1 == IpisInNet(utils_inet_ntoa(addr), g_acBrIpAddr, g_acBrMask))
        || (1 == IpisInNet(utils_inet_ntoa(addr), g_acPPPoEIpAddr, g_acPPPoEMask)))
    {
        get_ip_by_ifname(configuration.inbound_if, &stLocalAddr.sin_addr);
    }
    else
    {
        get_ip_by_ifname(configuration.outbound_if, &stLocalAddr.sin_addr);
    }
/*    
    if (g_lPacketDir == 0)
    {
        get_ip_by_ifname(configuration.outbound_if,&stLocalAddr.sin_addr);
//    stLocalAddr.sin_port = htons(atoi(pszLocalPort));
    }
    else
    {
        get_ip_by_ifname(configuration.inbound_if,&stLocalAddr.sin_addr);
//    stLocalAddr.sin_port = htons(atoi(pszLocalPort));
    }
*/
    stLocalAddr.sin_family = AF_INET;
    
    if (bind(sock, (struct sockaddr *)&stLocalAddr, sizeof(stLocalAddr)) < 0)
    {
    	perror("bind");
    }
    else
    {
        printsip("Sip: bind src ip:[%s]\r\n", inet_ntoa(stLocalAddr.sin_addr));
    }
   
    // if (0 != sip_udp_socket)
        #if 0
    if ((1 == IpisInNet(utils_inet_ntoa(addr), g_acBrIpAddr, g_acBrMask))
        || (1 == IpisInNet(utils_inet_ntoa(addr), g_acPPPoEIpAddr, g_acPPPoEMask)))
        #else
        if (0)
        #endif
    {
        sts = sendto(sock, buffer, size, 0,
             (const struct sockaddr *)&dst_addr,
             (socklen_t)sizeof(dst_addr));
   }
   else if (0 != sip_udp_socket)
   {
       sts = sendto(sip_udp_socket, buffer, size, 0,
                 (const struct sockaddr *)&dst_addr,
                 (socklen_t)sizeof(dst_addr));
   }
   else
   {
        printf("no proper socket found \r\n");
   }
   if (sts == -1) {
      if (errno != ECONNREFUSED) {
         ERROR("sendto() [%s:%i size=%i] call failed: %s",
               utils_inet_ntoa(addr),
               port, size, strerror(errno));
         close(sock);
         return STS_FAILURE;
      }
      DEBUGC(DBCLASS_BABBLE,"sendto() [%s:%i] call failed: %s",
             utils_inet_ntoa(addr), port, strerror(errno));
   }
   close(sock);
    }
   return STS_SUCCESS;
}
Example #14
0
static ssize_t rmnet_ctl_write(struct file *file, const char __user * buf,
		size_t size, loff_t *pos)
{
	int			status;
	size_t			total_len;
	void			*wbuf;
	void			*actual_data;
	struct ctrl_pkt		*cpkt;
	struct rmnet_ctrl_dev	*dev = file->private_data;

	if (!dev)
		return -ENODEV;

	if (size <= 0)
		return -EINVAL;

	if (!test_bit(RMNET_CTRL_DEV_READY, &dev->cudev->status))
		return -ENETRESET;

	DBG("%s: Writing %i bytes on %s\n", __func__, size, dev->name);

#ifdef CONFIG_QCT_9K_MODEM
	if (get_radio_flag() & RADIO_FLAG_MORE_LOG)
		pr_info("[RMNET] W: %i\n", size);
#endif

	total_len = size;

	if (test_bit(RMNET_CTRL_DEV_MUX_EN, &dev->status))
		total_len += sizeof(struct mux_hdr) + MAX_PAD_BYTES(4);

	wbuf = kmalloc(total_len , GFP_KERNEL);
	if (!wbuf)
		return -ENOMEM;

	cpkt = kmalloc(sizeof(struct ctrl_pkt), GFP_KERNEL);
	if (!cpkt) {
		kfree(wbuf);
		return -ENOMEM;
	}
	actual_data = cpkt->data = wbuf;
	cpkt->data_size = total_len;
	cpkt->ctxt = dev;

	if (test_bit(RMNET_CTRL_DEV_MUX_EN, &dev->status)) {
		actual_data = wbuf + sizeof(struct mux_hdr);
		rmnet_usb_ctrl_mux(dev->ch_id, cpkt);
	}

	status = copy_from_user(actual_data, buf, size);
	if (status) {
		dev_err(dev->devicep,
		"%s: Unable to copy data from userspace %d\n",
		__func__, status);
		kfree(wbuf);
		kfree(cpkt);
		return status;
	}
	DUMP_BUFFER("Write: ", size, buf);

#ifdef CONFIG_QCT_9K_MODEM
	status = rmnet_usb_ctrl_write(dev, cpkt, size);
	if (status == size)
		return size;
	else
		pr_err("[%s] status %d\n", __func__, status);
#else
	status = rmnet_usb_ctrl_write_cmd(dev->cudev,
			USB_CDC_SEND_ENCAPSULATED_COMMAND, 0, cpkt->data,
			cpkt->data_size);
	if (status > 0)
		dev->cudev->snd_encap_cmd_cnt++;

	kfree(cpkt->data);
	kfree(cpkt);
#endif

	return status;
}